Compare commits
18 Commits
master
...
villager_i
Author | SHA1 | Date |
---|---|---|
|
92d4e31740 | |
|
cda23513d8 | |
|
29aa8f8816 | |
|
0b35f3ad62 | |
|
693345fb27 | |
|
dd7af3b746 | |
|
f61036092b | |
|
b037c51ecc | |
|
6a85350364 | |
|
83fcf0dfd7 | |
|
2241697bb0 | |
|
b96406c3dc | |
|
8e38a7d761 | |
|
9eab701dcb | |
|
c4fdab8ab4 | |
|
d51f820d26 | |
|
32003abfbd | |
|
583819b8ef |
|
@ -31,12 +31,6 @@ Refer to [Minetest Lua API](https://github.com/minetest/minetest/blob/master/doc
|
||||||
|
|
||||||
Follow [Lua code style guidelines](https://dev.minetest.net/Lua_code_style_guidelines). Use tabs, not spaces for indentation (tab size = 8). Never use `minetest.env`.
|
Follow [Lua code style guidelines](https://dev.minetest.net/Lua_code_style_guidelines). Use tabs, not spaces for indentation (tab size = 8). Never use `minetest.env`.
|
||||||
|
|
||||||
If you do a translation, try detecting translational issues with `check_translate_files.py` - just run it from tools folder:
|
|
||||||
```bash
|
|
||||||
# python3 check_translate_files.py fr | less
|
|
||||||
```
|
|
||||||
(`fr` is a language code)
|
|
||||||
|
|
||||||
Check your code works as expected.
|
Check your code works as expected.
|
||||||
|
|
||||||
Commit & push your changes to a new branch (not master, one change per a branch).
|
Commit & push your changes to a new branch (not master, one change per a branch).
|
||||||
|
|
|
@ -70,11 +70,7 @@ an explanation.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
This game requires latest stable [Minetest](http://minetest.net) to run, please install
|
This game requires latest stable [Minetest](http://minetest.net) to run, please install
|
||||||
it first. Only latest stable version of Minetest is officially supported.
|
it first. Only stable versions of Minetest are officially supported.
|
||||||
There are lots of questions about Ubuntu, which has minetest-5.1.1 still.
|
|
||||||
Please, first of all, visit this page, it should fix the problem: https://launchpad.net/~minetestdevs/+archive/ubuntu/stable
|
|
||||||
Also, here is endless issue #123: https://git.minetest.land/MineClone5/MineClone5/issues/123 - really less preferable way.
|
|
||||||
|
|
||||||
There is no support for running MineClone 5 in development versions of Minetest.
|
There is no support for running MineClone 5 in development versions of Minetest.
|
||||||
|
|
||||||
To install MineClone 5 (if you haven't already), move this directory into the
|
To install MineClone 5 (if you haven't already), move this directory into the
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
# textdomain:mcl_explosions
|
|
||||||
@1 was caught in an explosion.=@1 es mòrt(a) dins una petarada.
|
|
|
@ -148,48 +148,16 @@ local chunk_scan_range = {
|
||||||
[ CS_NODES] = {LAST_BLOCK+1, LAST_BLOCK+1},
|
[ CS_NODES] = {LAST_BLOCK+1, LAST_BLOCK+1},
|
||||||
}
|
}
|
||||||
|
|
||||||
local EDGE_MIN = mcl_mapgen.EDGE_MIN
|
|
||||||
local EDGE_MAX = mcl_mapgen.EDGE_MAX
|
|
||||||
local function is_chunk_finished(minp)
|
local function is_chunk_finished(minp)
|
||||||
local center_x = minp.x + HALF_CS_NODES
|
local center = vector.add(minp, HALF_CS_NODES)
|
||||||
local center_y = minp.y + HALF_CS_NODES
|
for check_x = center.x - CS_NODES, center.x + CS_NODES, CS_NODES do
|
||||||
local center_z = minp.z + HALF_CS_NODES
|
for check_y = center.y - CS_NODES, center.y + CS_NODES, CS_NODES do
|
||||||
local from_x = center_x - CS_NODES
|
for check_z = center.z - CS_NODES, center.z + CS_NODES, CS_NODES do
|
||||||
local from_y = center_y - CS_NODES
|
local pos = vector.new(check_x, check_y, check_z)
|
||||||
local from_z = center_z - CS_NODES
|
if pos ~= center then
|
||||||
local to_x = center_x + CS_NODES
|
minetest_get_voxel_manip():read_from_map(pos, pos)
|
||||||
local to_y = center_y + CS_NODES
|
local node = minetest_get_node(pos)
|
||||||
local to_z = center_z + CS_NODES
|
|
||||||
if from_x < EDGE_MIN then from_x = center_x end
|
|
||||||
if from_y < EDGE_MIN then from_y = center_y end
|
|
||||||
if from_z < EDGE_MIN then from_z = center_z end
|
|
||||||
if to_x > EDGE_MAX then to_x = center_x end
|
|
||||||
if to_y > EDGE_MAX then to_y = center_y end
|
|
||||||
if to_z > EDGE_MAX then to_z = center_z end
|
|
||||||
for check_x = from_x, to_x, CS_NODES do
|
|
||||||
local are_we_in_central_chunk = check_x == center_x
|
|
||||||
for check_y = from_y, to_y, CS_NODES do
|
|
||||||
are_we_in_central_chunk = are_we_in_central_chunk and (check_y == center_y)
|
|
||||||
for check_z = from_z, to_z, CS_NODES do
|
|
||||||
are_we_in_central_chunk = are_we_in_central_chunk and (check_z == center_z)
|
|
||||||
if not are_we_in_central_chunk then
|
|
||||||
local check_pos = {x = check_x, y = check_y, z = check_z}
|
|
||||||
minetest_get_voxel_manip():read_from_map(check_pos, check_pos)
|
|
||||||
local node = minetest_get_node(check_pos)
|
|
||||||
if node.name == "ignore" then
|
if node.name == "ignore" then
|
||||||
-- return nil, means false, means, there is something to generate still,
|
|
||||||
-- (because one of adjacent chunks is unfinished - "ignore" means that),
|
|
||||||
-- means this chunk will be changed, at least one of its sides or corners
|
|
||||||
-- means it's unsafe to place anything there right now, it might disappar,
|
|
||||||
-- better to wait, see the diagram of conflict/ok areas per a single axis:
|
|
||||||
|
|
||||||
-- conflict| ok |conflict|conflict| ok |conflict|conflict| ok |conflict
|
|
||||||
-- (_________Chunk1_________)|(_________Chunk2_________)|(_________Chunk3_________)
|
|
||||||
-- [Block1]|[MidBlk]|[BlockN]|[Block1]|[MidBlk]|[BlockN]|[Block1]|[MidBlk]|[BlockN]
|
|
||||||
-- \_____________Chunk2-with-shell____________/
|
|
||||||
-- ...______Chunk1-with-shell________/ \________Chunk3-with-shell______...
|
|
||||||
-- Generation of chunk 1 AFFECTS 2 ^^^ ^^^ Generation of chunk 3 affects 2
|
|
||||||
-- ^^^^^^^^Chunk 2 gen. affects 1 and 3^^^^^^^^
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -394,17 +362,7 @@ minetest.register_on_generated(function(minp, maxp, chunkseed)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local register_on_generated_old = minetest.register_on_generated
|
minetest.register_on_generated = mcl_mapgen.register_chunk_generator
|
||||||
minetest.register_on_generated = function(...)
|
|
||||||
minetest.log("warning", "minetest.register_on_generated() is being called by the mod '"
|
|
||||||
.. minetest.get_current_modname() .. "'. MineClone5's map generation system avoids using "
|
|
||||||
.. "this callback to work around engine map generation issues. If possible please read "
|
|
||||||
.. "mods/CORE/mcl_mapgen/API.md and update " .. minetest.get_current_modname()
|
|
||||||
.. " to use the method described from there. MineClone5 makes no promises that "
|
|
||||||
.. "mapgen mods will be fully compatible with it, please test your server and use at "
|
|
||||||
.. "your own risk.")
|
|
||||||
return register_on_generated_old(...)
|
|
||||||
end
|
|
||||||
|
|
||||||
function mcl_mapgen.get_far_node(p)
|
function mcl_mapgen.get_far_node(p)
|
||||||
local p = p
|
local p = p
|
||||||
|
@ -450,21 +408,6 @@ function mcl_mapgen.get_chunk_number(pos) -- unsigned int
|
||||||
c.x + k_positive
|
c.x + k_positive
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Components of this game should register functions here to update their internal
|
|
||||||
-- state when external mods modify mapgen settings that they care about.
|
|
||||||
local settings_changed_callbacks = {}
|
|
||||||
function mcl_mapgen.register_on_settings_changed(callback)
|
|
||||||
table.insert(settings_changed_callbacks, callback)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- this is to be called by external mods after modifying these settings
|
|
||||||
-- to notify Mineclone that it needs to update local copies and whatever's based on them.
|
|
||||||
function mcl_mapgen.on_settings_changed()
|
|
||||||
for _, callback in pairs(settings_changed_callbacks) do
|
|
||||||
callback()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
mcl_mapgen.minecraft_height_limit = 256
|
mcl_mapgen.minecraft_height_limit = 256
|
||||||
|
|
||||||
mcl_mapgen.bedrock_is_rough = normal
|
mcl_mapgen.bedrock_is_rough = normal
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
mcl_util = {}
|
mcl_util = {}
|
||||||
|
|
||||||
local minetest_get_item_group = minetest.get_item_group
|
|
||||||
local minetest_get_meta = minetest.get_meta
|
|
||||||
local minetest_get_node = minetest.get_node
|
|
||||||
local minetest_get_node_timer = minetest.get_node_timer
|
|
||||||
local table_copy = table.copy
|
|
||||||
|
|
||||||
-- Updates all values in t using values from to*.
|
-- Updates all values in t using values from to*.
|
||||||
function table.update(t, ...)
|
function table.update(t, ...)
|
||||||
for _, to in ipairs{...} do
|
for _, to in ipairs{...} do
|
||||||
|
@ -39,6 +33,36 @@ function mcl_util.rotate_axis(itemstack, placer, pointed_thing)
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns position of the neighbor of a double chest node
|
||||||
|
-- or nil if node is invalid.
|
||||||
|
-- This function assumes that the large chest is actually intact
|
||||||
|
-- * pos: Position of the node to investigate
|
||||||
|
-- * param2: param2 of that node
|
||||||
|
-- * side: Which "half" the investigated node is. "left" or "right"
|
||||||
|
function mcl_util.get_double_container_neighbor_pos(pos, param2, side)
|
||||||
|
if side == "right" then
|
||||||
|
if param2 == 0 then
|
||||||
|
return {x=pos.x-1, y=pos.y, z=pos.z}
|
||||||
|
elseif param2 == 1 then
|
||||||
|
return {x=pos.x, y=pos.y, z=pos.z+1}
|
||||||
|
elseif param2 == 2 then
|
||||||
|
return {x=pos.x+1, y=pos.y, z=pos.z}
|
||||||
|
elseif param2 == 3 then
|
||||||
|
return {x=pos.x, y=pos.y, z=pos.z-1}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if param2 == 0 then
|
||||||
|
return {x=pos.x+1, y=pos.y, z=pos.z}
|
||||||
|
elseif param2 == 1 then
|
||||||
|
return {x=pos.x, y=pos.y, z=pos.z-1}
|
||||||
|
elseif param2 == 2 then
|
||||||
|
return {x=pos.x-1, y=pos.y, z=pos.z}
|
||||||
|
elseif param2 == 3 then
|
||||||
|
return {x=pos.x, y=pos.y, z=pos.z+1}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Iterates through all items in the given inventory and
|
-- Iterates through all items in the given inventory and
|
||||||
-- returns the slot of the first item which matches a condition.
|
-- returns the slot of the first item which matches a condition.
|
||||||
-- Returns nil if no item was found.
|
-- Returns nil if no item was found.
|
||||||
|
@ -63,7 +87,7 @@ end
|
||||||
|
|
||||||
-- Returns true if itemstack is a shulker box
|
-- Returns true if itemstack is a shulker box
|
||||||
local function is_not_shulker_box(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
|
||||||
|
|
||||||
|
@ -109,116 +133,136 @@ end
|
||||||
--- source_stack_id (optional): The inventory position ID of the source inventory to take the item from (-1 for slot of the first valid item; -1 is default)
|
--- source_stack_id (optional): The inventory position ID of the source inventory to take the item from (-1 for slot of the first valid item; -1 is default)
|
||||||
--- destination_list (optional): List name of the destination inventory. Default is normally "main"; "src" for furnace
|
--- destination_list (optional): List name of the destination inventory. Default is normally "main"; "src" for furnace
|
||||||
-- Returns true on success and false on failure.
|
-- Returns true on success and false on failure.
|
||||||
local SHULKER_BOX = 3
|
|
||||||
local FURNACE = 4
|
|
||||||
local DOUBLE_CHEST_LEFT = 5
|
|
||||||
local DOUBLE_CHEST_RIGHT = 6
|
|
||||||
local CONTAINER_GROUP_TO_LIST = {
|
|
||||||
[1] = "main",
|
|
||||||
[2] = "main",
|
|
||||||
[SHULKER_BOX] = "main",
|
|
||||||
[FURNACE] = "dst",
|
|
||||||
[DOUBLE_CHEST_LEFT] = "main",
|
|
||||||
[DOUBLE_CHEST_RIGHT] = "main",
|
|
||||||
}
|
|
||||||
function mcl_util.move_item_container(source_pos, destination_pos, source_list, source_stack_id, destination_list)
|
function mcl_util.move_item_container(source_pos, destination_pos, source_list, source_stack_id, destination_list)
|
||||||
local spos = table_copy(source_pos)
|
local dpos = table.copy(destination_pos)
|
||||||
local snode = minetest_get_node(spos)
|
local spos = table.copy(source_pos)
|
||||||
local sctype = minetest_get_item_group(snode.name, "container")
|
local snode = minetest.get_node(spos)
|
||||||
local default_source_list = CONTAINER_GROUP_TO_LIST[sctype]
|
local dnode = minetest.get_node(dpos)
|
||||||
if not default_source_list then return end
|
|
||||||
if sctype == DOUBLE_CHEST_RIGHT then
|
|
||||||
local sparam2 = snode.param2
|
|
||||||
if sparam2 == 0 then spos.x = spos.x - 1
|
|
||||||
elseif sparam2 == 1 then spos.z = spos.z + 1
|
|
||||||
elseif sparam2 == 2 then spos.x = spos.x + 1
|
|
||||||
elseif sparam2 == 3 then spos.z = spos.z - 1
|
|
||||||
end
|
|
||||||
snode = minetest_get_node(spos)
|
|
||||||
sctype = minetest_get_item_group(snode.name, "container")
|
|
||||||
if sctype ~= DOUBLE_CHEST_LEFT then return end
|
|
||||||
end
|
|
||||||
local smeta = minetest_get_meta(spos)
|
|
||||||
local sinv = smeta:get_inventory()
|
|
||||||
local source_list = source_list or default_source_list
|
|
||||||
|
|
||||||
local dpos = table_copy(destination_pos)
|
local dctype = minetest.get_item_group(dnode.name, "container")
|
||||||
local dnode = minetest_get_node(dpos)
|
local sctype = minetest.get_item_group(snode.name, "container")
|
||||||
local dctype = minetest_get_item_group(dnode.name, "container")
|
|
||||||
local default_destination_list = CONTAINER_GROUP_TO_LIST[sctype]
|
-- Container type 7 does not allow any movement
|
||||||
if not default_destination_list then return end
|
if sctype == 7 then
|
||||||
if dctype == DOUBLE_CHEST_RIGHT then
|
return false
|
||||||
local dparam2 = dnode.param2
|
|
||||||
if dparam2 == 0 then dpos.x = dpos.x - 1
|
|
||||||
elseif dparam2 == 1 then dpos.z = dpos.z + 1
|
|
||||||
elseif dparam2 == 2 then dpos.x = dpos.x + 1
|
|
||||||
elseif dparam2 == 3 then dpos.z = dpos.z - 1
|
|
||||||
end
|
|
||||||
dnode = minetest_get_node(dpos)
|
|
||||||
dctype = minetest_get_item_group(dnode.name, "container")
|
|
||||||
if dctype ~= DOUBLE_CHEST_LEFT then return end
|
|
||||||
end
|
end
|
||||||
local dmeta = minetest_get_meta(dpos)
|
|
||||||
|
-- Normalize double container by forcing to always use the left segment first
|
||||||
|
local function normalize_double_container(pos, node, ctype)
|
||||||
|
if ctype == 6 then
|
||||||
|
pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||||
|
if not pos then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
ctype = minetest.get_item_group(node.name, "container")
|
||||||
|
-- The left segment seems incorrect? We better bail out!
|
||||||
|
if ctype ~= 5 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return pos, node, ctype
|
||||||
|
end
|
||||||
|
|
||||||
|
spos, snode, sctype = normalize_double_container(spos, snode, sctype)
|
||||||
|
dpos, dnode, dctype = normalize_double_container(dpos, dnode, dctype)
|
||||||
|
if not spos or not dpos then return false end
|
||||||
|
|
||||||
|
local smeta = minetest.get_meta(spos)
|
||||||
|
local dmeta = minetest.get_meta(dpos)
|
||||||
|
|
||||||
|
local sinv = smeta:get_inventory()
|
||||||
local dinv = dmeta:get_inventory()
|
local dinv = dmeta:get_inventory()
|
||||||
|
|
||||||
|
-- Default source lists
|
||||||
|
if not source_list then
|
||||||
|
-- Main inventory for most container types
|
||||||
|
if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 or sctype == 7 then
|
||||||
|
source_list = "main"
|
||||||
|
-- Furnace: output
|
||||||
|
elseif sctype == 4 then
|
||||||
|
source_list = "dst"
|
||||||
|
-- Unknown source container type. Bail out
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Automatically select stack slot ID if set to automatic
|
-- Automatically select stack slot ID if set to automatic
|
||||||
local source_stack_id = source_stack_id or -1
|
if not source_stack_id then
|
||||||
|
source_stack_id = -1
|
||||||
|
end
|
||||||
if source_stack_id == -1 then
|
if source_stack_id == -1 then
|
||||||
local cond = nil
|
local cond = nil
|
||||||
-- Prevent shulker box inception
|
-- Prevent shulker box inception
|
||||||
if dctype == SHULKER_BOX then cond = is_not_shulker_box end
|
if dctype == 3 then
|
||||||
|
cond = is_not_shulker_box
|
||||||
|
end
|
||||||
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
|
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
|
||||||
if not source_stack_id then
|
if not source_stack_id then
|
||||||
if sctype == DOUBLE_CHEST_LEFT then
|
-- Try again if source is a double container
|
||||||
local sparam2 = snode.param2
|
if sctype == 5 then
|
||||||
if sparam2 == 0 then spos.x = spos.x + 1
|
spos = mcl_util.get_double_container_neighbor_pos(spos, snode.param2, "left")
|
||||||
elseif sparam2 == 1 then spos.z = spos.z - 1
|
smeta = minetest.get_meta(spos)
|
||||||
elseif sparam2 == 2 then spos.x = spos.x - 1
|
|
||||||
elseif sparam2 == 3 then spos.z = spos.z + 1
|
|
||||||
end
|
|
||||||
snode = minetest_get_node(spos)
|
|
||||||
sctype = minetest_get_item_group(snode.name, "container")
|
|
||||||
if sctype ~= DOUBLE_CHEST_RIGHT then return end
|
|
||||||
smeta = minetest_get_meta(spos)
|
|
||||||
sinv = smeta:get_inventory()
|
sinv = smeta:get_inventory()
|
||||||
|
|
||||||
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
|
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
|
||||||
|
if not source_stack_id then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not source_stack_id then return end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Abort transfer if shulker box wants to go into shulker box
|
-- Abort transfer if shulker box wants to go into shulker box
|
||||||
if dctype == SHULKER_BOX then
|
if dctype == 3 then
|
||||||
local stack = sinv:get_stack(source_list, source_stack_id)
|
local stack = sinv:get_stack(source_list, source_stack_id)
|
||||||
if stack and minetest_get_item_group(stack:get_name(), "shulker_box") == 1 then return end
|
if stack and minetest.get_item_group(stack:get_name(), "shulker_box") == 1 then
|
||||||
end
|
return false
|
||||||
|
|
||||||
local destination_list = destination_list or default_destination_list
|
|
||||||
-- Move item
|
|
||||||
local ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
|
|
||||||
-- Try transfer to neighbor node if transfer failed and double container
|
|
||||||
if not ok then
|
|
||||||
if dctype == DOUBLE_CHEST_LEFT then
|
|
||||||
local dparam2 = dnode.param2
|
|
||||||
if dparam2 == 0 then dpos.x = dpos.x + 1
|
|
||||||
elseif dparam2 == 1 then dpos.z = dpos.z - 1
|
|
||||||
elseif dparam2 == 2 then dpos.x = dpos.x - 1
|
|
||||||
elseif dparam2 == 3 then dpos.z = dpos.z + 1
|
|
||||||
end
|
|
||||||
dnode = minetest_get_node(dpos)
|
|
||||||
dctype = minetest_get_item_group(dnode.name, "container")
|
|
||||||
if dctype ~= DOUBLE_CHEST_RIGHT then return end
|
|
||||||
dmeta = minetest_get_meta(dpos)
|
|
||||||
dinv = dmeta:get_inventory()
|
|
||||||
ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Update furnace
|
-- Container type 7 does not allow any placement
|
||||||
if ok and dctype == FURNACE then
|
if dctype == 7 then
|
||||||
-- Start furnace's timer function, it will sort out whether furnace can burn or not.
|
return false
|
||||||
minetest_get_node_timer(dpos):start(1.0)
|
|
||||||
end
|
end
|
||||||
return ok
|
|
||||||
|
-- If it's a container, put it into the container
|
||||||
|
if dctype ~= 0 then
|
||||||
|
-- Automatically select a destination list if omitted
|
||||||
|
if not destination_list then
|
||||||
|
-- Main inventory for most container types
|
||||||
|
if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 or dctype == 7 then
|
||||||
|
destination_list = "main"
|
||||||
|
-- Furnace source slot
|
||||||
|
elseif dctype == 4 then
|
||||||
|
destination_list = "src"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if destination_list then
|
||||||
|
-- Move item
|
||||||
|
local ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
|
||||||
|
|
||||||
|
-- Try transfer to neighbor node if transfer failed and double container
|
||||||
|
if not ok and dctype == 5 then
|
||||||
|
dpos = mcl_util.get_double_container_neighbor_pos(dpos, dnode.param2, "left")
|
||||||
|
dmeta = minetest.get_meta(dpos)
|
||||||
|
dinv = dmeta:get_inventory()
|
||||||
|
|
||||||
|
ok = mcl_util.move_item(sinv, source_list, source_stack_id, dinv, destination_list)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update furnace
|
||||||
|
if ok and dctype == 4 then
|
||||||
|
-- Start furnace's timer function, it will sort out whether furnace can burn or not.
|
||||||
|
minetest.get_node_timer(dpos):start(1.0)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the ID of the first non-empty slot in the given inventory list
|
-- Returns the ID of the first non-empty slot in the given inventory list
|
||||||
|
@ -248,7 +292,7 @@ function mcl_util.generate_on_place_plant_function(condition)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Call on_rightclick if the pointed node defines it
|
-- Call on_rightclick if the pointed node defines it
|
||||||
local node = minetest_get_node(pointed_thing.under)
|
local node = minetest.get_node(pointed_thing.under)
|
||||||
if placer and not placer:get_player_control().sneak then
|
if placer and not placer:get_player_control().sneak then
|
||||||
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
|
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
|
||||||
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
|
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
|
||||||
|
@ -256,8 +300,8 @@ function mcl_util.generate_on_place_plant_function(condition)
|
||||||
end
|
end
|
||||||
|
|
||||||
local place_pos
|
local place_pos
|
||||||
local def_under = minetest.registered_nodes[minetest_get_node(pointed_thing.under).name]
|
local def_under = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
|
||||||
local def_above = minetest.registered_nodes[minetest_get_node(pointed_thing.above).name]
|
local def_above = minetest.registered_nodes[minetest.get_node(pointed_thing.above).name]
|
||||||
if not def_under or not def_above then
|
if not def_under or not def_above then
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
@ -315,7 +359,7 @@ function mcl_util.call_on_rightclick(itemstack, player, pointed_thing)
|
||||||
-- Call on_rightclick if the pointed node defines it
|
-- Call on_rightclick if the pointed node defines it
|
||||||
if pointed_thing and pointed_thing.type == "node" then
|
if pointed_thing and pointed_thing.type == "node" then
|
||||||
local pos = pointed_thing.under
|
local pos = pointed_thing.under
|
||||||
local node = minetest_get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
if player and not player:get_player_control().sneak then
|
if player and not player:get_player_control().sneak then
|
||||||
local nodedef = minetest.registered_nodes[node.name]
|
local nodedef = minetest.registered_nodes[node.name]
|
||||||
local on_rightclick = nodedef and nodedef.on_rightclick
|
local on_rightclick = nodedef and nodedef.on_rightclick
|
||||||
|
@ -328,7 +372,7 @@ end
|
||||||
|
|
||||||
function mcl_util.calculate_durability(itemstack)
|
function mcl_util.calculate_durability(itemstack)
|
||||||
local unbreaking_level = mcl_enchanting.get_enchantment(itemstack, "unbreaking")
|
local unbreaking_level = mcl_enchanting.get_enchantment(itemstack, "unbreaking")
|
||||||
local armor_uses = minetest_get_item_group(itemstack:get_name(), "mcl_armor_uses")
|
local armor_uses = minetest.get_item_group(itemstack:get_name(), "mcl_armor_uses")
|
||||||
|
|
||||||
local uses
|
local uses
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,11 @@ mcl_worlds = {}
|
||||||
|
|
||||||
local get_connected_players = minetest.get_connected_players
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
|
||||||
local min1, min2, min3
|
|
||||||
local max1, max2, max3
|
|
||||||
local get_local_settings = function()
|
|
||||||
min1, min2, min3 = mcl_mapgen.overworld.min, mcl_mapgen.end_.min, mcl_mapgen.nether.min
|
|
||||||
max1, max2, max3 = mcl_mapgen.overworld.max, mcl_mapgen.end_.max, mcl_mapgen.nether.max+128
|
|
||||||
end
|
|
||||||
get_local_settings()
|
|
||||||
mcl_mapgen.register_on_settings_changed(get_local_settings)
|
|
||||||
|
|
||||||
-- 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
|
||||||
|
local min1, min2, min3 = mcl_mapgen.overworld.min, mcl_mapgen.end_.min, mcl_mapgen.nether.min
|
||||||
|
local max1, max2, max3 = mcl_mapgen.overworld.max, mcl_mapgen.end_.max, mcl_mapgen.nether.max+128
|
||||||
function mcl_worlds.is_in_void(pos)
|
function mcl_worlds.is_in_void(pos)
|
||||||
local y = pos.y
|
local y = pos.y
|
||||||
local void = not ((y < max1 and y > min1) or (y < max2 and y > min2) or (y < max3 and y > min3))
|
local void = not ((y < max1 and y > min1) or (y < max2 and y > min2) or (y < max3 and y > min3))
|
||||||
|
|
|
@ -21,11 +21,9 @@ local S = minetest.get_translator("extra_mobs")
|
||||||
local followitem = "mcl_farming:sweet_berry"
|
local followitem = "mcl_farming:sweet_berry"
|
||||||
|
|
||||||
local fox = {
|
local fox = {
|
||||||
type = "animal",
|
type = "monster",
|
||||||
passive = false,
|
passive = false,
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
skittish = true,
|
|
||||||
runaway = true,
|
|
||||||
hp_min = 10,
|
hp_min = 10,
|
||||||
hp_max = 10,
|
hp_max = 10,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
|
@ -34,20 +32,9 @@ local fox = {
|
||||||
attack_type = "dogfight",
|
attack_type = "dogfight",
|
||||||
damage = 2,
|
damage = 2,
|
||||||
reach = 1.5,
|
reach = 1.5,
|
||||||
jump = true,
|
|
||||||
makes_footstep_sound = true,
|
|
||||||
walk_velocity = 3,
|
|
||||||
run_velocity = 6,
|
|
||||||
follow_velocity = 2,
|
|
||||||
follow = followitem,
|
|
||||||
pathfinding = 1,
|
|
||||||
fear_height = 4,
|
|
||||||
view_range = 16,
|
|
||||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3},
|
collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3},
|
||||||
specific_attack = { "mobs_mc:chicken", "extra_mobs:cod", "extra_mobs:salmon" },
|
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "extra_mobs_fox.b3d",
|
mesh = "extra_mobs_fox.b3d",
|
||||||
rotate = 270,
|
|
||||||
textures = { {
|
textures = { {
|
||||||
"extra_mobs_fox.png",
|
"extra_mobs_fox.png",
|
||||||
"extra_mobs_trans.png",
|
"extra_mobs_trans.png",
|
||||||
|
@ -55,6 +42,10 @@ local fox = {
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
sounds = {
|
sounds = {
|
||||||
},
|
},
|
||||||
|
jump = true,
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
walk_velocity = 3,
|
||||||
|
run_velocity = 6,
|
||||||
drops = {
|
drops = {
|
||||||
},
|
},
|
||||||
animation = {
|
animation = {
|
||||||
|
@ -72,9 +63,9 @@ local fox = {
|
||||||
lay_start = 34,
|
lay_start = 34,
|
||||||
lay_end = 34,
|
lay_end = 34,
|
||||||
},
|
},
|
||||||
|
runaway = true,
|
||||||
on_spawn = function(self)
|
on_spawn = function(self)
|
||||||
if minetest.find_node_near(self.object:get_pos(), 4, "mcl_core:snow") ~= nil
|
if minetest.find_node_near(self.object:get_pos(), 4, "mcl_core:snow") ~= nil or minetest.find_node_near(self.object:get_pos(), 4, "mcl_core:dirt_with_grass_snow") ~= nil then
|
||||||
or minetest.find_node_near(self.object:get_pos(), 4, "mcl_core:dirt_with_grass_snow") ~= nil then
|
|
||||||
self.object:set_properties({textures={"extra_mobs_artic_fox.png", "extra_mobs_trans.png"}})
|
self.object:set_properties({textures={"extra_mobs_artic_fox.png", "extra_mobs_trans.png"}})
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -92,11 +83,7 @@ local fox = {
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
for _,object in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 8)) do
|
for _,object in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 8)) do
|
||||||
if object
|
if object and not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "extra_mobs:fox" and self.state ~= "attack" and math.random(1, 500) == 1 then
|
||||||
and not object:is_player()
|
|
||||||
and object:get_luaentity()
|
|
||||||
and object:get_luaentity().name == "extra_mobs:fox"
|
|
||||||
and self.state ~= "attack" and math.random(1, 500) == 1 then
|
|
||||||
self.horny = true
|
self.horny = true
|
||||||
end
|
end
|
||||||
local lp = object:get_pos()
|
local lp = object:get_pos()
|
||||||
|
@ -106,30 +93,15 @@ local fox = {
|
||||||
y = lp.y - s.y,
|
y = lp.y - s.y,
|
||||||
z = lp.z - s.z
|
z = lp.z - s.z
|
||||||
}
|
}
|
||||||
-- scare logic
|
if object and object:is_player() and not object:get_player_control().sneak or not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mobs_mc:wolf" then
|
||||||
if (object
|
self.state = "runaway"
|
||||||
and object:is_player()
|
self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0})
|
||||||
and not object:get_player_control().sneak)
|
if self.reach > vector.distance(self.object:get_pos(), object:get_pos()) and self.timer > .9 then
|
||||||
or (not object:is_player()
|
self.timer = 0
|
||||||
and object:get_luaentity()
|
object:punch(self.object, 1.0, {
|
||||||
and object:get_luaentity().name == "mobs_mc:wolf") then
|
full_punch_interval = 1.0,
|
||||||
-- don't keep setting it once it's set
|
damage_groups = {fleshy = self.damage}
|
||||||
if not self.state == "runaway" then
|
}, nil)
|
||||||
self.state = "runaway"
|
|
||||||
self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0})
|
|
||||||
end
|
|
||||||
-- if it is within a distance of the player or wolf
|
|
||||||
if 6 > vector.distance(self.object:get_pos(), object:get_pos()) then
|
|
||||||
self.timer = self.timer + 1
|
|
||||||
-- have some time before getting scared
|
|
||||||
if self.timer > 6 then
|
|
||||||
self.timer = 0
|
|
||||||
-- punch the fox for the player, but don't do any damage
|
|
||||||
self.object:punch(object, 0, {
|
|
||||||
full_punch_interval = 0,
|
|
||||||
damage_groups = {fleshy = 0}
|
|
||||||
}, nil)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -137,6 +109,10 @@ local fox = {
|
||||||
do_punch = function(self)
|
do_punch = function(self)
|
||||||
self.state = "runaway"
|
self.state = "runaway"
|
||||||
end,
|
end,
|
||||||
|
follow = followitem,
|
||||||
|
fear_height = 4,
|
||||||
|
view_range = 16,
|
||||||
|
specific_attack = { "mobs_mc:chicken", "extra_mobs:cod", "extra_mobs:salmon" },
|
||||||
}
|
}
|
||||||
|
|
||||||
mobs:register_mob("extra_mobs:fox", fox)
|
mobs:register_mob("extra_mobs:fox", fox)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# textdomain:extra_mobs
|
# textdomain:extra_mobs
|
||||||
Hoglin=Hoglin
|
Hoglin=Hoglin
|
||||||
Piglin=Piglin
|
piglin=Piglin
|
||||||
Piglin Brute=Piglin Barbare
|
piglin Brute=Piglin Barbare
|
||||||
Strider=Arpenteur
|
Strider=Arpenteur
|
||||||
Fox=Renard
|
Fox=Renard
|
||||||
Cod=Poisson
|
Cod=Poisson
|
||||||
Salmon=Saumon
|
Salmon=Saumon
|
||||||
Dolphin=Dauphin
|
dolphin=Dauphin
|
||||||
Glow Squid=Pieuvre Lumineuse
|
Glow Squid=Pieuvre Lumineuse
|
||||||
Glow Ink Sac=Sac d'Encre Lumineuse
|
Glow Ink Sac=Sac d'Encre Lumineuse
|
|
@ -1,11 +1,11 @@
|
||||||
# textdomain:extra_mobs
|
# textdomain:extra_mobs
|
||||||
Hoglin=
|
Hoglin=
|
||||||
Piglin=
|
piglin=
|
||||||
Piglin Brute=
|
piglin Brute=
|
||||||
Strider=
|
Strider=
|
||||||
Fox=
|
Fox=
|
||||||
Cod=
|
Cod=
|
||||||
Salmon=
|
Salmon=
|
||||||
Dolphin=
|
dolphin=
|
||||||
Glow Squid=
|
Glow Squid=
|
||||||
Glow Ink Sac=
|
Glow Ink Sac=
|
|
@ -1,13 +0,0 @@
|
||||||
# textdomain: mcl_boats
|
|
||||||
Acacia Boat=Barca de Cacièr
|
|
||||||
Birch Boat=Barca de Bèç
|
|
||||||
Boat=Barca
|
|
||||||
Boats are used to travel on the surface of water.= Las Barcas permetàn de vogar per l'aiga.
|
|
||||||
Dark Oak Boat=Barca de Jàrric
|
|
||||||
Jungle Boat=Barca de Jungla
|
|
||||||
Oak Boat=Barca de Ròure
|
|
||||||
Obsidian Boat=Barca d'Obsidiana
|
|
||||||
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.=Fasetz un clic dreit sobre una sorça d'aiga per botar la barca. Fasetz un clic dreit sobre la barca per ne'n dintrar. Utilisatz [Esquèrra] e [Dreita] per menar, [Davant] per accelerar, e [Darrèir] per alentir o recular. Utilizatz [S'acatar] per o quitar, picatz la barca per o faire tombar en objèct.
|
|
||||||
Spruce Boat=Barca de Sap
|
|
||||||
Water vehicle=Veïcule d'Aiga
|
|
||||||
Sneak to dismount=S'acatar per descendre
|
|
|
@ -1,3 +0,0 @@
|
||||||
# textdomain: mcl_falling_nodes
|
|
||||||
@1 was smashed by a falling anvil.=@1 fuguèt espotit per una enclutge.
|
|
||||||
@1 was smashed by a falling block.=@1 fuguèt espotit per un blòc.
|
|
|
@ -156,10 +156,6 @@ minetest.register_globalstep(function(dtime)
|
||||||
object:set_velocity({x=0,y=0,z=0})
|
object:set_velocity({x=0,y=0,z=0})
|
||||||
object:set_acceleration({x=0,y=0,z=0})
|
object:set_acceleration({x=0,y=0,z=0})
|
||||||
|
|
||||||
if object._flowing then
|
|
||||||
object._flowing = false
|
|
||||||
end
|
|
||||||
|
|
||||||
object:move_to(checkpos)
|
object:move_to(checkpos)
|
||||||
|
|
||||||
pool[name] = pool[name] + 1
|
pool[name] = pool[name] + 1
|
||||||
|
@ -799,9 +795,6 @@ minetest.register_entity(":__builtin:item", {
|
||||||
|
|
||||||
local oldvel = self.object:get_velocity() -- v is vector, vel is velocity
|
local oldvel = self.object:get_velocity() -- v is vector, vel is velocity
|
||||||
|
|
||||||
-- apply gravity *before* drag computations
|
|
||||||
oldvel.y = oldvel.y - get_gravity() * dtime
|
|
||||||
|
|
||||||
-- drag
|
-- drag
|
||||||
local fluid_drag = item_drop_settings.fluid_drag
|
local fluid_drag = item_drop_settings.fluid_drag
|
||||||
|
|
||||||
|
@ -816,6 +809,12 @@ minetest.register_entity(":__builtin:item", {
|
||||||
newv.y = newv.y - (oldvel.y - newv.y) * fluid_drag * dtime
|
newv.y = newv.y - (oldvel.y - newv.y) * fluid_drag * dtime
|
||||||
newv.z = newv.z - (oldvel.z - newv.z) * fluid_drag * dtime
|
newv.z = newv.z - (oldvel.z - newv.z) * fluid_drag * dtime
|
||||||
|
|
||||||
|
newv.y = newv.y + -0.22 -- (keep slight downward thrust from previous version of code)
|
||||||
|
-- NOTE: is there any particular reason we have this, anyway?
|
||||||
|
-- since fluid drag is now on, we could as well just
|
||||||
|
-- apply gravity here; drag will slow down the fall
|
||||||
|
-- realistically
|
||||||
|
|
||||||
self.object:set_velocity({x = oldvel.x + newv.x * dtime, y = oldvel.y + newv.y * dtime, z = oldvel.z + newv.z * dtime})
|
self.object:set_velocity({x = oldvel.x + newv.x * dtime, y = oldvel.y + newv.y * dtime, z = oldvel.z + newv.z * dtime})
|
||||||
|
|
||||||
self.physical_state = true
|
self.physical_state = true
|
||||||
|
|
|
@ -417,7 +417,7 @@ function mobs:register_mob(name, def)
|
||||||
|
|
||||||
--on_breed = def.on_breed,
|
--on_breed = def.on_breed,
|
||||||
|
|
||||||
on_grown = def.on_grown,
|
--on_grown = def.on_grown,
|
||||||
|
|
||||||
--on_detach_child = mob_detach_child,
|
--on_detach_child = mob_detach_child,
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ local function land_state_switch(self, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
--ignore everything else if following
|
--ignore everything else if following
|
||||||
if mobs.check_following(self, dtime) and
|
if mobs.check_following(self) and
|
||||||
(not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) and
|
(not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) and
|
||||||
(not self.breed_timer or (self.breed_timer and self.breed_timer == 0)) then
|
(not self.breed_timer or (self.breed_timer and self.breed_timer == 0)) then
|
||||||
self.state = "follow"
|
self.state = "follow"
|
||||||
|
@ -984,7 +984,7 @@ function mobs.mob_step(self, dtime)
|
||||||
|
|
||||||
--go get the closest player
|
--go get the closest player
|
||||||
if attacking then
|
if attacking then
|
||||||
mobs.do_head_logic(self, dtime, attacking)
|
|
||||||
self.memory = 6 --6 seconds of memory
|
self.memory = 6 --6 seconds of memory
|
||||||
|
|
||||||
--set initial punch timer
|
--set initial punch timer
|
||||||
|
@ -1040,7 +1040,6 @@ function mobs.mob_step(self, dtime)
|
||||||
--don't break eye contact
|
--don't break eye contact
|
||||||
if self.hostile and self.attacking then
|
if self.hostile and self.attacking then
|
||||||
mobs.set_yaw_while_attacking(self)
|
mobs.set_yaw_while_attacking(self)
|
||||||
mobs.do_head_logic(self, dtime, self.attacking)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--perfectly reset pause_timer
|
--perfectly reset pause_timer
|
||||||
|
|
|
@ -26,8 +26,6 @@ local math_random = math.random
|
||||||
|_|
|
|_|
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
local minetest_line_of_sight = minetest.line_of_sight
|
|
||||||
|
|
||||||
mobs.explode_attack_walk = function(self,dtime)
|
mobs.explode_attack_walk = function(self,dtime)
|
||||||
|
|
||||||
--this needs an exception
|
--this needs an exception
|
||||||
|
@ -38,27 +36,17 @@ mobs.explode_attack_walk = function(self,dtime)
|
||||||
|
|
||||||
mobs.set_yaw_while_attacking(self)
|
mobs.set_yaw_while_attacking(self)
|
||||||
|
|
||||||
local pos = self.object:get_pos()
|
local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos())
|
||||||
local attack_pos = self.attacking:get_pos()
|
|
||||||
local distance_from_attacking = vector_distance(pos, attack_pos)
|
|
||||||
|
|
||||||
--make mob walk up to player within 2 nodes distance then start exploding
|
--make mob walk up to player within 2 nodes distance then start exploding
|
||||||
if (
|
if distance_from_attacking >= self.reach and
|
||||||
distance_from_attacking >= self.reach and
|
--don't allow explosion to cancel unless out of the reach boundary
|
||||||
|
not (self.explosion_animation and self.explosion_animation > 0 and distance_from_attacking <= self.defuse_reach) then
|
||||||
|
|
||||||
--don't allow explosion to cancel unless out of the reach boundary
|
|
||||||
not (self.explosion_animation and self.explosion_animation > 0 and distance_from_attacking <= self.defuse_reach) or
|
|
||||||
--don't allow creeper to finish exploding animation if can't see target
|
|
||||||
not minetest_line_of_sight(
|
|
||||||
{x = pos.x, y = pos.y + self.eye_height, z = pos.z},
|
|
||||||
{x = attack_pos.x, y = attack_pos.y + (self.attacking.eye_height or 0), z = attack_pos.z}
|
|
||||||
)
|
|
||||||
) then
|
|
||||||
mobs.set_velocity(self, self.run_velocity)
|
mobs.set_velocity(self, self.run_velocity)
|
||||||
mobs.set_mob_animation(self,"run")
|
mobs.set_mob_animation(self,"run")
|
||||||
|
|
||||||
mobs.reverse_explosion_animation(self,dtime)
|
mobs.reverse_explosion_animation(self,dtime)
|
||||||
|
|
||||||
else
|
else
|
||||||
mobs.set_velocity(self,0)
|
mobs.set_velocity(self,0)
|
||||||
|
|
||||||
|
|
|
@ -1715,9 +1715,591 @@ local do_env_damage = function(self)
|
||||||
damage_effect(self, dmg)
|
damage_effect(self, dmg)
|
||||||
self.health = self.health - dmg
|
self.health = self.health - dmg
|
||||||
end
|
end
|
||||||
if check_for_death(self, "drowning", {type = "environment",
|
end
|
||||||
pos = pos, node = self.standing_in}) then
|
end
|
||||||
return true
|
|
||||||
|
-- swimmers flop when out of their element, and swim again when back in
|
||||||
|
if self.fly then
|
||||||
|
local s = self.object:get_pos()
|
||||||
|
if not flight_check(self, s) then
|
||||||
|
|
||||||
|
self.state = "flop"
|
||||||
|
self.object:set_acceleration({x = 0, y = DEFAULT_FALL_SPEED, z = 0})
|
||||||
|
|
||||||
|
local sdef = minetest.registered_nodes[self.standing_on]
|
||||||
|
-- Flop on ground
|
||||||
|
if sdef and sdef.walkable then
|
||||||
|
mob_sound(self, "flop")
|
||||||
|
self.object:set_velocity({
|
||||||
|
x = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
|
||||||
|
y = FLOP_HEIGHT,
|
||||||
|
z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
set_animation(self, "stand", true)
|
||||||
|
|
||||||
|
return
|
||||||
|
elseif self.state == "flop" then
|
||||||
|
self.state = "stand"
|
||||||
|
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||||
|
set_velocity(self, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- dogshoot attack switch and counter function
|
||||||
|
local dogswitch = function(self, dtime)
|
||||||
|
|
||||||
|
-- switch mode not activated
|
||||||
|
if not self.dogshoot_switch
|
||||||
|
or not dtime then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
self.dogshoot_count = self.dogshoot_count + dtime
|
||||||
|
|
||||||
|
if (self.dogshoot_switch == 1
|
||||||
|
and self.dogshoot_count > self.dogshoot_count_max)
|
||||||
|
or (self.dogshoot_switch == 2
|
||||||
|
and self.dogshoot_count > self.dogshoot_count2_max) then
|
||||||
|
|
||||||
|
self.dogshoot_count = 0
|
||||||
|
|
||||||
|
if self.dogshoot_switch == 1 then
|
||||||
|
self.dogshoot_switch = 2
|
||||||
|
else
|
||||||
|
self.dogshoot_switch = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.dogshoot_switch
|
||||||
|
end
|
||||||
|
|
||||||
|
local function go_to_pos(entity,b)
|
||||||
|
if not entity then return end
|
||||||
|
local s=entity.object:get_pos()
|
||||||
|
if vector.distance(b,s) < 1 then
|
||||||
|
--set_velocity(entity,0)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local v = { x = b.x - s.x, z = b.z - s.z }
|
||||||
|
local yaw = (math.atan(v.z / v.x) + math.pi / 2) - entity.rotate
|
||||||
|
if b.x > s.x then yaw = yaw + math.pi end
|
||||||
|
entity.object:set_yaw(yaw)
|
||||||
|
set_velocity(entity,entity.follow_velocity)
|
||||||
|
mobs:set_animation(entity, "walk")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- execute current state (stand, walk, run, attacks)
|
||||||
|
-- returns true if mob has died
|
||||||
|
local do_states = function(self, dtime)
|
||||||
|
local yaw = self.object:get_yaw() or 0
|
||||||
|
|
||||||
|
if self.state == "stand" then
|
||||||
|
if random(1, 4) == 1 then
|
||||||
|
|
||||||
|
local s = self.object:get_pos()
|
||||||
|
local objs = minetest.get_objects_inside_radius(s, 3)
|
||||||
|
|
||||||
|
for n = 1, #objs do
|
||||||
|
|
||||||
|
if objs[n]:is_player() then
|
||||||
|
lp = objs[n]:get_pos()
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- look at any players nearby, otherwise turn randomly
|
||||||
|
if self.look_at_players then
|
||||||
|
|
||||||
|
local vec = {
|
||||||
|
x = lp.x - s.x,
|
||||||
|
z = lp.z - s.z
|
||||||
|
}
|
||||||
|
|
||||||
|
yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate
|
||||||
|
|
||||||
|
if lp.x > s.x then yaw = yaw + pi end
|
||||||
|
else
|
||||||
|
yaw = yaw + random(-0.5, 0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
yaw = set_yaw(self, yaw, 8)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_velocity(self, 0)
|
||||||
|
set_animation(self, "stand")
|
||||||
|
|
||||||
|
-- npc's ordered to stand stay standing
|
||||||
|
if self.type ~= "npc"
|
||||||
|
or self.order ~= "stand" then
|
||||||
|
|
||||||
|
if self.walk_chance ~= 0
|
||||||
|
and self.facing_fence ~= true
|
||||||
|
and random(1, 100) <= self.walk_chance
|
||||||
|
and is_at_cliff_or_danger(self) == false then
|
||||||
|
|
||||||
|
set_velocity(self, self.walk_velocity)
|
||||||
|
self.state = "walk"
|
||||||
|
set_animation(self, "walk")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif self.state == "gowp" then
|
||||||
|
local p = self.object:get_pos()
|
||||||
|
if not p or not self._target then return end
|
||||||
|
if vector.distance(p,self._target) < 2 or #self.waypoints == 0 then
|
||||||
|
self.waypoints = nil
|
||||||
|
self._target = nil
|
||||||
|
self.current_target = nil
|
||||||
|
self.state = "walk"
|
||||||
|
if self.callback_arrived then return self.callback_arrived(self) end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if not self.current_target or vector.distance(p,self.current_target) < 1.5 then
|
||||||
|
self.current_target = table.remove(self.waypoints, 1)
|
||||||
|
--minetest.log("nextwp:".. tostring(self.current_target) )
|
||||||
|
elseif self.current_target then
|
||||||
|
go_to_pos(self,self.current_target)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then
|
||||||
|
self.waypoints=minetest.find_path(p,self._target,150,1,4)
|
||||||
|
self.current_target = nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not self.current_target then
|
||||||
|
--minetest.log("no path")
|
||||||
|
self.state = "walk"
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif self.state == "walk" then
|
||||||
|
local s = self.object:get_pos()
|
||||||
|
local lp = nil
|
||||||
|
|
||||||
|
-- is there something I need to avoid?
|
||||||
|
if (self.water_damage > 0
|
||||||
|
and self.lava_damage > 0)
|
||||||
|
or self.breath_max ~= -1 then
|
||||||
|
|
||||||
|
lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"})
|
||||||
|
|
||||||
|
elseif self.water_damage > 0 then
|
||||||
|
|
||||||
|
lp = minetest.find_node_near(s, 1, {"group:water"})
|
||||||
|
|
||||||
|
elseif self.lava_damage > 0 then
|
||||||
|
|
||||||
|
lp = minetest.find_node_near(s, 1, {"group:lava"})
|
||||||
|
|
||||||
|
elseif self.fire_damage > 0 then
|
||||||
|
|
||||||
|
lp = minetest.find_node_near(s, 1, {"group:fire"})
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local is_in_danger = false
|
||||||
|
if lp then
|
||||||
|
-- If mob in or on dangerous block, look for land
|
||||||
|
if (is_node_dangerous(self, self.standing_in) or
|
||||||
|
is_node_dangerous(self, self.standing_on)) or (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) and (not self.fly) then
|
||||||
|
is_in_danger = true
|
||||||
|
|
||||||
|
-- If mob in or on dangerous block, look for land
|
||||||
|
if is_in_danger then
|
||||||
|
-- Better way to find shore - copied from upstream
|
||||||
|
lp = minetest.find_nodes_in_area_under_air(
|
||||||
|
{x = s.x - 5, y = s.y - 0.5, z = s.z - 5},
|
||||||
|
{x = s.x + 5, y = s.y + 1, z = s.z + 5},
|
||||||
|
{"group:solid"})
|
||||||
|
|
||||||
|
lp = #lp > 0 and lp[random(#lp)]
|
||||||
|
|
||||||
|
-- did we find land?
|
||||||
|
if lp then
|
||||||
|
|
||||||
|
local vec = {
|
||||||
|
x = lp.x - s.x,
|
||||||
|
z = lp.z - s.z
|
||||||
|
}
|
||||||
|
|
||||||
|
yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate
|
||||||
|
|
||||||
|
|
||||||
|
if lp.x > s.x then yaw = yaw + pi end
|
||||||
|
|
||||||
|
-- look towards land and move in that direction
|
||||||
|
yaw = set_yaw(self, yaw, 6)
|
||||||
|
set_velocity(self, self.walk_velocity)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- A danger is near but mob is not inside
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Randomly turn
|
||||||
|
if random(1, 100) <= 30 then
|
||||||
|
yaw = yaw + random(-0.5, 0.5)
|
||||||
|
yaw = set_yaw(self, yaw, 8)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
yaw = set_yaw(self, yaw, 8)
|
||||||
|
|
||||||
|
-- otherwise randomly turn
|
||||||
|
elseif random(1, 100) <= 30 then
|
||||||
|
|
||||||
|
yaw = yaw + random(-0.5, 0.5)
|
||||||
|
yaw = set_yaw(self, yaw, 8)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- stand for great fall or danger or fence in front
|
||||||
|
local cliff_or_danger = false
|
||||||
|
if is_in_danger then
|
||||||
|
cliff_or_danger = is_at_cliff_or_danger(self)
|
||||||
|
end
|
||||||
|
if self.facing_fence == true
|
||||||
|
or cliff_or_danger
|
||||||
|
or random(1, 100) <= 30 then
|
||||||
|
|
||||||
|
set_velocity(self, 0)
|
||||||
|
self.state = "stand"
|
||||||
|
set_animation(self, "stand")
|
||||||
|
local yaw = self.object:get_yaw() or 0
|
||||||
|
yaw = set_yaw(self, yaw + 0.78, 8)
|
||||||
|
else
|
||||||
|
|
||||||
|
set_velocity(self, self.walk_velocity)
|
||||||
|
|
||||||
|
if flight_check(self)
|
||||||
|
and self.animation
|
||||||
|
and self.animation.fly_start
|
||||||
|
and self.animation.fly_end then
|
||||||
|
set_animation(self, "fly")
|
||||||
|
else
|
||||||
|
set_animation(self, "walk")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- runaway when punched
|
||||||
|
elseif self.state == "runaway" then
|
||||||
|
|
||||||
|
self.runaway_timer = self.runaway_timer + 1
|
||||||
|
|
||||||
|
-- stop after 5 seconds or when at cliff
|
||||||
|
if self.runaway_timer > 5
|
||||||
|
or is_at_cliff_or_danger(self) then
|
||||||
|
self.runaway_timer = 0
|
||||||
|
set_velocity(self, 0)
|
||||||
|
self.state = "stand"
|
||||||
|
set_animation(self, "stand")
|
||||||
|
local yaw = self.object:get_yaw() or 0
|
||||||
|
yaw = set_yaw(self, yaw + 0.78, 8)
|
||||||
|
else
|
||||||
|
set_velocity(self, self.run_velocity)
|
||||||
|
set_animation(self, "run")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- attack routines (explode, dogfight, shoot, dogshoot)
|
||||||
|
elseif self.state == "attack" then
|
||||||
|
|
||||||
|
local s = self.object:get_pos()
|
||||||
|
local p = self.attack:get_pos() or s
|
||||||
|
|
||||||
|
-- stop attacking if player invisible or out of range
|
||||||
|
if not self.attack
|
||||||
|
or not self.attack:get_pos()
|
||||||
|
or not object_in_range(self, self.attack)
|
||||||
|
or self.attack:get_hp() <= 0
|
||||||
|
or (self.attack:is_player() and mobs.invis[ self.attack:get_player_name() ]) then
|
||||||
|
|
||||||
|
self.state = "stand"
|
||||||
|
set_velocity(self, 0)
|
||||||
|
set_animation(self, "stand")
|
||||||
|
self.attack = nil
|
||||||
|
self.v_start = false
|
||||||
|
self.timer = 0
|
||||||
|
self.blinktimer = 0
|
||||||
|
self.path.way = nil
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- calculate distance from mob and enemy
|
||||||
|
local dist = vector.distance(p, s)
|
||||||
|
|
||||||
|
if self.attack_type == "explode" then
|
||||||
|
|
||||||
|
local vec = {
|
||||||
|
x = p.x - s.x,
|
||||||
|
z = p.z - s.z
|
||||||
|
}
|
||||||
|
|
||||||
|
yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate
|
||||||
|
|
||||||
|
if p.x > s.x then yaw = yaw + pi end
|
||||||
|
|
||||||
|
yaw = set_yaw(self, yaw, 0, dtime)
|
||||||
|
|
||||||
|
local node_break_radius = self.explosion_radius or 1
|
||||||
|
local entity_damage_radius = self.explosion_damage_radius
|
||||||
|
or (node_break_radius * 2)
|
||||||
|
|
||||||
|
-- start timer when in reach and line of sight
|
||||||
|
if not self.v_start
|
||||||
|
and dist <= self.reach
|
||||||
|
and line_of_sight(self, s, p, 2) then
|
||||||
|
|
||||||
|
self.v_start = true
|
||||||
|
self.timer = 0
|
||||||
|
self.blinktimer = 0
|
||||||
|
mob_sound(self, "fuse", nil, false)
|
||||||
|
|
||||||
|
-- stop timer if out of reach or direct line of sight
|
||||||
|
elseif self.allow_fuse_reset
|
||||||
|
and self.v_start
|
||||||
|
and (dist >= self.explosiontimer_reset_radius
|
||||||
|
or not line_of_sight(self, s, p, 2)) then
|
||||||
|
self.v_start = false
|
||||||
|
self.timer = 0
|
||||||
|
self.blinktimer = 0
|
||||||
|
self.blinkstatus = false
|
||||||
|
remove_texture_mod(self, "^[brighten")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- walk right up to player unless the timer is active
|
||||||
|
if self.v_start and (self.stop_to_explode or dist < self.reach) then
|
||||||
|
set_velocity(self, 0)
|
||||||
|
else
|
||||||
|
set_velocity(self, self.run_velocity)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.animation and self.animation.run_start then
|
||||||
|
set_animation(self, "run")
|
||||||
|
else
|
||||||
|
set_animation(self, "walk")
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.v_start then
|
||||||
|
|
||||||
|
self.timer = self.timer + dtime
|
||||||
|
self.blinktimer = (self.blinktimer or 0) + dtime
|
||||||
|
|
||||||
|
if self.blinktimer > 0.2 then
|
||||||
|
|
||||||
|
self.blinktimer = 0
|
||||||
|
|
||||||
|
if self.blinkstatus then
|
||||||
|
remove_texture_mod(self, "^[brighten")
|
||||||
|
else
|
||||||
|
add_texture_mod(self, "^[brighten")
|
||||||
|
end
|
||||||
|
|
||||||
|
self.blinkstatus = not self.blinkstatus
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.timer > self.explosion_timer then
|
||||||
|
|
||||||
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
|
if mod_explosions then
|
||||||
|
if mobs_griefing and not minetest.is_protected(pos, "") then
|
||||||
|
mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { drop_chance = 1.0 }, self.object)
|
||||||
|
else
|
||||||
|
minetest.sound_play(self.sounds.explode, {
|
||||||
|
pos = pos,
|
||||||
|
gain = 1.0,
|
||||||
|
max_hear_distance = self.sounds.distance or 32
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
entity_physics(pos, entity_damage_radius)
|
||||||
|
effect(pos, 32, "mcl_particles_smoke.png", nil, nil, node_break_radius, 1, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
mcl_burning.extinguish(self.object)
|
||||||
|
self.object:remove()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif self.attack_type == "dogfight"
|
||||||
|
or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 2)
|
||||||
|
or (self.attack_type == "dogshoot" and dist <= self.reach and dogswitch(self) == 0) then
|
||||||
|
|
||||||
|
if self.fly
|
||||||
|
and dist > self.reach then
|
||||||
|
|
||||||
|
local p1 = s
|
||||||
|
local me_y = floor(p1.y)
|
||||||
|
local p2 = p
|
||||||
|
local p_y = floor(p2.y + 1)
|
||||||
|
local v = self.object:get_velocity()
|
||||||
|
|
||||||
|
if flight_check(self, s) then
|
||||||
|
|
||||||
|
if me_y < p_y then
|
||||||
|
|
||||||
|
self.object:set_velocity({
|
||||||
|
x = v.x,
|
||||||
|
y = 1 * self.walk_velocity,
|
||||||
|
z = v.z
|
||||||
|
})
|
||||||
|
|
||||||
|
elseif me_y > p_y then
|
||||||
|
|
||||||
|
self.object:set_velocity({
|
||||||
|
x = v.x,
|
||||||
|
y = -1 * self.walk_velocity,
|
||||||
|
z = v.z
|
||||||
|
})
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if me_y < p_y then
|
||||||
|
|
||||||
|
self.object:set_velocity({
|
||||||
|
x = v.x,
|
||||||
|
y = 0.01,
|
||||||
|
z = v.z
|
||||||
|
})
|
||||||
|
|
||||||
|
elseif me_y > p_y then
|
||||||
|
|
||||||
|
self.object:set_velocity({
|
||||||
|
x = v.x,
|
||||||
|
y = -0.01,
|
||||||
|
z = v.z
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- rnd: new movement direction
|
||||||
|
if self.path.following
|
||||||
|
and self.path.way
|
||||||
|
and self.attack_type ~= "dogshoot" then
|
||||||
|
|
||||||
|
-- no paths longer than 50
|
||||||
|
if #self.path.way > 50
|
||||||
|
or dist < self.reach then
|
||||||
|
self.path.following = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local p1 = self.path.way[1]
|
||||||
|
|
||||||
|
if not p1 then
|
||||||
|
self.path.following = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if abs(p1.x-s.x) + abs(p1.z - s.z) < 0.6 then
|
||||||
|
-- reached waypoint, remove it from queue
|
||||||
|
table.remove(self.path.way, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set new temporary target
|
||||||
|
p = {x = p1.x, y = p1.y, z = p1.z}
|
||||||
|
end
|
||||||
|
|
||||||
|
local vec = {
|
||||||
|
x = p.x - s.x,
|
||||||
|
z = p.z - s.z
|
||||||
|
}
|
||||||
|
|
||||||
|
yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate
|
||||||
|
|
||||||
|
if p.x > s.x then yaw = yaw + pi end
|
||||||
|
|
||||||
|
yaw = set_yaw(self, yaw, 0, dtime)
|
||||||
|
|
||||||
|
-- move towards enemy if beyond mob reach
|
||||||
|
if dist > self.reach then
|
||||||
|
|
||||||
|
-- path finding by rnd
|
||||||
|
if self.pathfinding -- only if mob has pathfinding enabled
|
||||||
|
and enable_pathfinding then
|
||||||
|
|
||||||
|
smart_mobs(self, s, p, dist, dtime)
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_at_cliff_or_danger(self) then
|
||||||
|
|
||||||
|
set_velocity(self, 0)
|
||||||
|
set_animation(self, "stand")
|
||||||
|
local yaw = self.object:get_yaw() or 0
|
||||||
|
yaw = set_yaw(self, yaw + 0.78, 8)
|
||||||
|
else
|
||||||
|
|
||||||
|
if self.path.stuck then
|
||||||
|
set_velocity(self, self.walk_velocity)
|
||||||
|
else
|
||||||
|
set_velocity(self, self.run_velocity)
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.animation and self.animation.run_start then
|
||||||
|
set_animation(self, "run")
|
||||||
|
else
|
||||||
|
set_animation(self, "walk")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else -- rnd: if inside reach range
|
||||||
|
|
||||||
|
self.path.stuck = false
|
||||||
|
self.path.stuck_timer = 0
|
||||||
|
self.path.following = false -- not stuck anymore
|
||||||
|
|
||||||
|
set_velocity(self, 0)
|
||||||
|
|
||||||
|
if not self.custom_attack then
|
||||||
|
|
||||||
|
if self.timer > 1 then
|
||||||
|
|
||||||
|
self.timer = 0
|
||||||
|
|
||||||
|
if self.double_melee_attack
|
||||||
|
and random(1, 2) == 1 then
|
||||||
|
set_animation(self, "punch2")
|
||||||
|
else
|
||||||
|
set_animation(self, "punch")
|
||||||
|
end
|
||||||
|
|
||||||
|
local p2 = p
|
||||||
|
local s2 = s
|
||||||
|
|
||||||
|
p2.y = p2.y + .5
|
||||||
|
s2.y = s2.y + .5
|
||||||
|
|
||||||
|
if line_of_sight(self, p2, s2) == true then
|
||||||
|
|
||||||
|
-- play attack sound
|
||||||
|
mob_sound(self, "attack")
|
||||||
|
|
||||||
|
-- punch player (or what player is attached to)
|
||||||
|
local attached = self.attack:get_attach()
|
||||||
|
if attached then
|
||||||
|
self.attack = attached
|
||||||
|
end
|
||||||
|
self.attack:punch(self.object, 1.0, {
|
||||||
|
full_punch_interval = 1.0,
|
||||||
|
damage_groups = {fleshy = self.damage}
|
||||||
|
}, nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else -- call custom attack every second
|
||||||
|
if self.custom_attack
|
||||||
|
and self.timer > 1 then
|
||||||
|
|
||||||
|
self.timer = 0
|
||||||
|
|
||||||
|
self.custom_attack(self, p)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.breath = math_min(self.breath_max, self.breath + 1)
|
self.breath = math_min(self.breath_max, self.breath + 1)
|
||||||
|
@ -1819,8 +2401,20 @@ local do_jump = function(self)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.walk_chance == 0
|
local function check_item_pickup(self)
|
||||||
or minetest_registered_items[nod.name].walkable then
|
if self.pick_up and #self.pick_up > 0 then
|
||||||
|
for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),2)) do
|
||||||
|
local l=o:get_luaentity()
|
||||||
|
if l and l.name == "__builtin:item" then
|
||||||
|
for k,v in pairs(self.pick_up) do
|
||||||
|
if self.on_pick_up and l.itemstring:find(v) then
|
||||||
|
if self.on_pick_up(self,l) == nil then o:remove() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if minetest_get_item_group(nod.name, "fence") == 0
|
if minetest_get_item_group(nod.name, "fence") == 0
|
||||||
and minetest_get_item_group(nod.name, "fence_gate") == 0
|
and minetest_get_item_group(nod.name, "fence_gate") == 0
|
||||||
|
@ -2236,9 +2830,12 @@ function do_states(self)
|
||||||
|
|
||||||
lp = minetest_find_node_near(s, 1, {"group:lava"})
|
lp = minetest_find_node_near(s, 1, {"group:lava"})
|
||||||
|
|
||||||
elseif self.fire_damage > 0 then
|
-- main mob function
|
||||||
|
local mob_step = function(self, dtime)
|
||||||
lp = minetest_find_node_near(s, 1, {"group:fire"})
|
check_item_pickup(self)
|
||||||
|
if not self.fire_resistant then
|
||||||
|
mcl_burning.tick(self.object, dtime, self)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2553,7 +3150,161 @@ function do_states(self)
|
||||||
z = p.z - s.z
|
z = p.z - s.z
|
||||||
}
|
}
|
||||||
|
|
||||||
yaw = (atan(vec.z / vec.x) + math_pi / 2) - self.rotate
|
minetest.register_entity(name, {
|
||||||
|
|
||||||
|
use_texture_alpha = def.use_texture_alpha,
|
||||||
|
stepheight = def.stepheight or 0.6,
|
||||||
|
name = name,
|
||||||
|
description = def.description,
|
||||||
|
type = def.type,
|
||||||
|
attack_type = def.attack_type,
|
||||||
|
fly = def.fly,
|
||||||
|
fly_in = def.fly_in or {"air", "__airlike"},
|
||||||
|
owner = def.owner or "",
|
||||||
|
order = def.order or "",
|
||||||
|
on_die = def.on_die,
|
||||||
|
spawn_small_alternative = def.spawn_small_alternative,
|
||||||
|
do_custom = def.do_custom,
|
||||||
|
jump_height = def.jump_height or 4, -- was 6
|
||||||
|
rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2
|
||||||
|
lifetimer = def.lifetimer or 57.73,
|
||||||
|
hp_min = scale_difficulty(def.hp_min, 5, 1),
|
||||||
|
hp_max = scale_difficulty(def.hp_max, 10, 1),
|
||||||
|
xp_min = def.xp_min or 0,
|
||||||
|
xp_max = def.xp_max or 0,
|
||||||
|
xp_timestamp = 0,
|
||||||
|
breath_max = def.breath_max or 15,
|
||||||
|
breathes_in_water = def.breathes_in_water or false,
|
||||||
|
physical = true,
|
||||||
|
collisionbox = collisionbox,
|
||||||
|
selectionbox = def.selectionbox or def.collisionbox,
|
||||||
|
visual = def.visual,
|
||||||
|
visual_size = def.visual_size or {x = 1, y = 1},
|
||||||
|
mesh = def.mesh,
|
||||||
|
makes_footstep_sound = def.makes_footstep_sound or false,
|
||||||
|
view_range = def.view_range or 16,
|
||||||
|
walk_velocity = def.walk_velocity or 1,
|
||||||
|
run_velocity = def.run_velocity or 2,
|
||||||
|
damage = scale_difficulty(def.damage, 0, 0),
|
||||||
|
light_damage = def.light_damage or 0,
|
||||||
|
sunlight_damage = def.sunlight_damage or 0,
|
||||||
|
water_damage = def.water_damage or 0,
|
||||||
|
lava_damage = def.lava_damage or 8,
|
||||||
|
fire_damage = def.fire_damage or 1,
|
||||||
|
suffocation = def.suffocation or true,
|
||||||
|
fall_damage = def.fall_damage or 1,
|
||||||
|
fall_speed = def.fall_speed or DEFAULT_FALL_SPEED, -- must be lower than -2
|
||||||
|
drops = def.drops or {},
|
||||||
|
armor = def.armor or 100,
|
||||||
|
on_rightclick = create_mob_on_rightclick(def.on_rightclick),
|
||||||
|
arrow = def.arrow,
|
||||||
|
shoot_interval = def.shoot_interval,
|
||||||
|
sounds = def.sounds or {},
|
||||||
|
animation = def.animation,
|
||||||
|
follow = def.follow,
|
||||||
|
jump = def.jump ~= false,
|
||||||
|
walk_chance = def.walk_chance or 50,
|
||||||
|
attacks_monsters = def.attacks_monsters or false,
|
||||||
|
group_attack = def.group_attack or false,
|
||||||
|
passive = def.passive or false,
|
||||||
|
knock_back = def.knock_back ~= false,
|
||||||
|
shoot_offset = def.shoot_offset or 0,
|
||||||
|
floats = def.floats or 1, -- floats in water by default
|
||||||
|
floats_on_lava = def.floats_on_lava or 0,
|
||||||
|
replace_rate = def.replace_rate,
|
||||||
|
replace_what = def.replace_what,
|
||||||
|
replace_with = def.replace_with,
|
||||||
|
replace_offset = def.replace_offset or 0,
|
||||||
|
on_replace = def.on_replace,
|
||||||
|
timer = 0,
|
||||||
|
env_damage_timer = 0,
|
||||||
|
tamed = false,
|
||||||
|
pause_timer = 0,
|
||||||
|
horny = false,
|
||||||
|
hornytimer = 0,
|
||||||
|
gotten = false,
|
||||||
|
health = 0,
|
||||||
|
reach = def.reach or 3,
|
||||||
|
htimer = 0,
|
||||||
|
texture_list = def.textures,
|
||||||
|
child_texture = def.child_texture,
|
||||||
|
docile_by_day = def.docile_by_day or false,
|
||||||
|
time_of_day = 0.5,
|
||||||
|
fear_height = def.fear_height or 0,
|
||||||
|
runaway = def.runaway,
|
||||||
|
runaway_timer = 0,
|
||||||
|
pathfinding = def.pathfinding,
|
||||||
|
immune_to = def.immune_to or {},
|
||||||
|
explosion_radius = def.explosion_radius, -- LEGACY
|
||||||
|
explosion_damage_radius = def.explosion_damage_radius, -- LEGACY
|
||||||
|
explosiontimer_reset_radius = def.explosiontimer_reset_radius,
|
||||||
|
explosion_timer = def.explosion_timer or 3,
|
||||||
|
allow_fuse_reset = def.allow_fuse_reset ~= false,
|
||||||
|
stop_to_explode = def.stop_to_explode ~= false,
|
||||||
|
custom_attack = def.custom_attack,
|
||||||
|
double_melee_attack = def.double_melee_attack,
|
||||||
|
dogshoot_switch = def.dogshoot_switch,
|
||||||
|
dogshoot_count = 0,
|
||||||
|
dogshoot_count_max = def.dogshoot_count_max or 5,
|
||||||
|
dogshoot_count2_max = def.dogshoot_count2_max or (def.dogshoot_count_max or 5),
|
||||||
|
attack_animals = def.attack_animals or false,
|
||||||
|
specific_attack = def.specific_attack,
|
||||||
|
runaway_from = def.runaway_from,
|
||||||
|
owner_loyal = def.owner_loyal,
|
||||||
|
facing_fence = false,
|
||||||
|
_cmi_is_mob = true,
|
||||||
|
pushable = def.pushable or true,
|
||||||
|
|
||||||
|
|
||||||
|
-- MCL2 extensions
|
||||||
|
teleport = teleport,
|
||||||
|
do_teleport = def.do_teleport,
|
||||||
|
spawn_class = def.spawn_class,
|
||||||
|
ignores_nametag = def.ignores_nametag or false,
|
||||||
|
rain_damage = def.rain_damage or 0,
|
||||||
|
glow = def.glow,
|
||||||
|
can_despawn = can_despawn,
|
||||||
|
child = def.child or false,
|
||||||
|
texture_mods = {},
|
||||||
|
shoot_arrow = def.shoot_arrow,
|
||||||
|
sounds_child = def.sounds_child,
|
||||||
|
pick_up = def.pick_up,
|
||||||
|
explosion_strength = def.explosion_strength,
|
||||||
|
suffocation_timer = 0,
|
||||||
|
follow_velocity = def.follow_velocity or 2.4,
|
||||||
|
instant_death = def.instant_death or false,
|
||||||
|
fire_resistant = def.fire_resistant or false,
|
||||||
|
fire_damage_resistant = def.fire_damage_resistant or false,
|
||||||
|
ignited_by_sunlight = def.ignited_by_sunlight or false,
|
||||||
|
-- End of MCL2 extensions
|
||||||
|
|
||||||
|
on_spawn = def.on_spawn,
|
||||||
|
|
||||||
|
on_blast = def.on_blast or do_tnt,
|
||||||
|
|
||||||
|
on_step = mob_step,
|
||||||
|
|
||||||
|
do_punch = def.do_punch,
|
||||||
|
|
||||||
|
on_punch = mob_punch,
|
||||||
|
|
||||||
|
on_breed = def.on_breed,
|
||||||
|
|
||||||
|
on_grown = def.on_grown,
|
||||||
|
|
||||||
|
on_pick_up = def.on_pick_up,
|
||||||
|
|
||||||
|
on_detach_child = mob_detach_child,
|
||||||
|
|
||||||
|
on_activate = function(self, staticdata, dtime)
|
||||||
|
--this is a temporary hack so mobs stop
|
||||||
|
--glitching and acting really weird with the
|
||||||
|
--default built in engine collision detection
|
||||||
|
self.object:set_properties({
|
||||||
|
collide_with_objects = false,
|
||||||
|
})
|
||||||
|
return mob_activate(self, staticdata, def, dtime)
|
||||||
|
end,
|
||||||
|
|
||||||
if p.x > s.x then yaw = yaw + math_pi end
|
if p.x > s.x then yaw = yaw + math_pi end
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||||
local vector = vector
|
local vector = vector
|
||||||
|
|
||||||
--check to see if someone nearby has some tasty food
|
--check to see if someone nearby has some tasty food
|
||||||
mobs.check_following = function(self, dtime) -- returns true or false
|
mobs.check_following = function(self) -- returns true or false
|
||||||
--ignore
|
--ignore
|
||||||
if not self.follow then
|
if not self.follow then
|
||||||
self.following_person = nil
|
self.following_person = nil
|
||||||
|
@ -15,7 +15,6 @@ mobs.check_following = function(self, dtime) -- returns true or false
|
||||||
|
|
||||||
--check if the follower is a player incase they log out
|
--check if the follower is a player incase they log out
|
||||||
if follower and follower:is_player() then
|
if follower and follower:is_player() then
|
||||||
mobs.do_head_logic(self, dtime, follower)
|
|
||||||
local stack = follower:get_wielded_item()
|
local stack = follower:get_wielded_item()
|
||||||
--safety check
|
--safety check
|
||||||
if not stack then
|
if not stack then
|
||||||
|
@ -146,12 +145,11 @@ end
|
||||||
|
|
||||||
--make the baby grow up
|
--make the baby grow up
|
||||||
mobs.baby_grow_up = function(self)
|
mobs.baby_grow_up = function(self)
|
||||||
self.baby = nil
|
self.baby = nil
|
||||||
self.visual_size = self.backup_visual_size
|
self.visual_size = self.backup_visual_size
|
||||||
self.collisionbox = self.backup_collisionbox
|
self.collisionbox = self.backup_collisionbox
|
||||||
self.selectionbox = self.backup_selectionbox
|
self.selectionbox = self.backup_selectionbox
|
||||||
self.object:set_properties(self)
|
self.object:set_properties(self)
|
||||||
if self.on_grown then self.on_grown(self) end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--makes the baby grow up faster with diminishing returns
|
--makes the baby grow up faster with diminishing returns
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
local math = math
|
local math = math
|
||||||
local vector = vector
|
local vector = vector
|
||||||
local debug_head = minetest.settings:get_bool("mcl_debug_head_code", false)
|
|
||||||
|
|
||||||
--converts yaw to degrees
|
--converts yaw to degrees
|
||||||
local degrees = function(yaw)
|
local degrees = function(yaw)
|
||||||
return yaw*180.0/math.pi
|
return yaw*180.0/math.pi
|
||||||
end
|
end
|
||||||
|
|
||||||
mobs.do_head_logic = function(self, dtime, player)
|
mobs.do_head_logic = function(self,dtime)
|
||||||
if not self.has_head == true then return end
|
|
||||||
local player = player or minetest.get_player_by_name("singleplayer")
|
local player = minetest.get_player_by_name("singleplayer")
|
||||||
|
|
||||||
local look_at = player:get_pos()
|
local look_at = player:get_pos()
|
||||||
look_at.y = look_at.y + player:get_properties().eye_height
|
look_at.y = look_at.y + player:get_properties().eye_height
|
||||||
|
@ -26,16 +25,15 @@ mobs.do_head_logic = function(self, dtime, player)
|
||||||
|
|
||||||
pos = vector.add(pos, head_offset)
|
pos = vector.add(pos, head_offset)
|
||||||
|
|
||||||
if debug_head then
|
minetest.add_particle({
|
||||||
minetest.add_particle({
|
pos = pos,
|
||||||
pos = pos,
|
velocity = {x=0, y=0, z=0},
|
||||||
velocity = {x=0, y=0, z=0},
|
acceleration = {x=0, y=0, z=0},
|
||||||
acceleration = {x=0, y=0, z=0},
|
expirationtime = 0.2,
|
||||||
expirationtime = 0.2,
|
size = 1,
|
||||||
size = 1,
|
texture = "default_dirt.png",
|
||||||
texture = "default_dirt.png",
|
})
|
||||||
})
|
|
||||||
end
|
|
||||||
local bone_pos = vector.new(0,0,0)
|
local bone_pos = vector.new(0,0,0)
|
||||||
|
|
||||||
--(horizontal)
|
--(horizontal)
|
||||||
|
@ -91,21 +89,10 @@ mobs.do_head_logic = function(self, dtime, player)
|
||||||
head_pitch = head_pitch + self.head_pitch_modifier
|
head_pitch = head_pitch + self.head_pitch_modifier
|
||||||
end
|
end
|
||||||
|
|
||||||
local head_bone = self.head_bone
|
if self.swap_y_with_x then
|
||||||
if (type(head_bone) == "table") then
|
self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),degrees(head_yaw),0))
|
||||||
for _, v in pairs(head_bone) do
|
|
||||||
if self.swap_y_with_x then
|
|
||||||
self.object:set_bone_position(v, bone_pos, vector.new(degrees(head_pitch),degrees(head_yaw),0))
|
|
||||||
else
|
|
||||||
self.object:set_bone_position(v, bone_pos, vector.new(degrees(head_pitch),0,degrees(head_yaw)))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
if self.swap_y_with_x then
|
self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),0,degrees(head_yaw)))
|
||||||
self.object:set_bone_position(head_bone, bone_pos, vector.new(degrees(head_pitch),degrees(head_yaw),0))
|
|
||||||
else
|
|
||||||
self.object:set_bone_position(head_bone, bone_pos, vector.new(degrees(head_pitch),0,degrees(head_yaw)))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
--set_bone_position([bone, position, rotation])
|
--set_bone_position([bone, position, rotation])
|
||||||
end
|
end
|
|
@ -1,11 +1,11 @@
|
||||||
# textdomain: mcl_mobs
|
# textdomain: mcl_mobs
|
||||||
Peaceful mode active! No monsters will spawn.=Mode paisible actif ! Aucun monstre n'apparaîtra.
|
Peaceful mode active! No monsters will spawn.=Mode paisible actif! Aucun monstre n'apparaîtra.
|
||||||
This allows you to place a single mob.=Cela vous permet de placer un seul mob.
|
This allows you to place a single mob.=Cela vous permet de placer un seul mob.
|
||||||
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.=Placez-le là où vous voulez que le mob apparaisse. Les animaux apparaîtront apprivoisés, sauf si vous maintenez la touche furtive enfoncée pendant le placement. Si vous le placez sur un générateur de mob, vous changez le mob qu'il génère.
|
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.=Placez-le là où vous voulez que le mob apparaisse. Les animaux apparaîtront apprivoisés, sauf si vous maintenez la touche furtive enfoncée pendant le placement. Si vous le placez sur un générateur de mob, vous changez le mob qu'il génère.
|
||||||
You need the “maphack” privilege to change the mob spawner.=Vous avez besoin du privilège "maphack" pour changer le générateur de mob.
|
You need the “maphack” privilege to change the mob spawner.=Vous avez besoin du privilège "maphack" pour changer le générateur de mob.
|
||||||
Name Tag=Étiquette de nom
|
Name Tag=Étiquette de nom
|
||||||
A name tag is an item to name a mob.=Une étiquette de nom est un élément pour nommer un mob.
|
A name tag is an item to name a mob.=Une étiquette de nom est un élément pour nommer un mob.
|
||||||
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.=Avant d'utiliser l'étiquette de nom, vous devez définir un nom sur une enclume. Ensuite, vous pouvez utiliser l'étiquette de nom pour nommer un mob. Cela utilise l'étiquette de nom.
|
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.=Avant d'utiliser l'étiquette de nom, vous devez définir un nom sur une enclume. Ensuite, vous pouvez utiliser l'étiquette de nom pour nommer un mob. Cela utilise l'étiquette de nom.
|
||||||
Only peaceful mobs allowed!=Seuls les mobs pacifiques sont autorisés !
|
Only peaceful mobs allowed!=Seuls les mobs pacifiques sont autorisés!
|
||||||
Give names to mobs=Donne des noms aux mobs
|
Give names to mobs=Donne des noms aux mobs
|
||||||
Set name at anvil=Définir le nom sur l'enclume
|
Set name at anvil=Définir le nom sur l'enclume
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
# textdomain:mcl_paintings
|
|
||||||
Painting=Pintura
|
|
|
@ -74,4 +74,3 @@ Tool Smith=Fabriquant d'outil
|
||||||
Cleric=Clerc
|
Cleric=Clerc
|
||||||
Nitwit=Crétin
|
Nitwit=Crétin
|
||||||
Protects you from death while wielding it=Vous protège de la mort en le maniant
|
Protects you from death while wielding it=Vous protège de la mort en le maniant
|
||||||
Pillager=Pillard
|
|
|
@ -1,77 +0,0 @@
|
||||||
# textdomain: mobs_mc
|
|
||||||
Totem of Undying=Totèm d'Imortalitat
|
|
||||||
A totem of undying is a rare artifact which may safe you from certain death.=Un totèm d'imortalitat es un artefacte rara que pòt vos sauvar d'una mòrt surada.
|
|
||||||
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.=
|
|
||||||
Agent=Agent
|
|
||||||
Bat=Ratapenada
|
|
||||||
Blaze=Blaze
|
|
||||||
Chicken=Pola
|
|
||||||
Cow=Vacha
|
|
||||||
Mooshroom=Champavacha
|
|
||||||
Creeper=Creeper
|
|
||||||
Ender Dragon=Drac de l'End
|
|
||||||
Enderman=Òme de l'End
|
|
||||||
Endermite=Endarna
|
|
||||||
Ghast=Trèva
|
|
||||||
Elder Guardian=Gardian Ainat
|
|
||||||
Guardian=Gardian
|
|
||||||
Horse=Ega
|
|
||||||
Skeleton Horse=Ega Esquelèta
|
|
||||||
Zombie Horse=Ega Mòrtaviva
|
|
||||||
Donkey=Asne
|
|
||||||
Mule=Miula
|
|
||||||
Iron Golem=Golèm de Fèrre
|
|
||||||
Llama=Lama
|
|
||||||
Ocelot=Ocelòt
|
|
||||||
Parrot=Papagai
|
|
||||||
Pig=Pòrc
|
|
||||||
Polar Bear=Ors Polar
|
|
||||||
Rabbit=Lapin
|
|
||||||
Killer Bunny=Lapin Tuaire
|
|
||||||
The Killer Bunny=Lo Lapin Tuaire
|
|
||||||
Sheep=Moton
|
|
||||||
Shulker=
|
|
||||||
Silverfish=
|
|
||||||
Skeleton=
|
|
||||||
Stray=
|
|
||||||
Wither Skeleton=
|
|
||||||
Magma Cube=
|
|
||||||
Slime=
|
|
||||||
Snow Golem=
|
|
||||||
Spider=
|
|
||||||
Cave Spider=
|
|
||||||
Squid=
|
|
||||||
Vex=
|
|
||||||
Evoker=
|
|
||||||
Illusioner=
|
|
||||||
Villager=
|
|
||||||
Vindicator=
|
|
||||||
Zombie Villager=
|
|
||||||
Witch=
|
|
||||||
Wither=
|
|
||||||
Wolf=
|
|
||||||
Husk=
|
|
||||||
Zombie=
|
|
||||||
Zombie Pigman=
|
|
||||||
Iron Horse Armor=
|
|
||||||
Iron horse armor can be worn by horses to increase their protection from harm a bit.=
|
|
||||||
Golden Horse Armor=
|
|
||||||
Golden horse armor can be worn by horses to increase their protection from harm.=
|
|
||||||
Diamond Horse Armor=
|
|
||||||
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=
|
|
||||||
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=
|
|
||||||
Farmer=
|
|
||||||
Fisherman=
|
|
||||||
Fletcher=
|
|
||||||
Shepherd=
|
|
||||||
Librarian=
|
|
||||||
Cartographer=
|
|
||||||
Armorer=
|
|
||||||
Leatherworker=
|
|
||||||
Butcher=
|
|
||||||
Weapon Smith=
|
|
||||||
Tool Smith=
|
|
||||||
Cleric=
|
|
||||||
Nitwit=
|
|
||||||
Protects you from death while wielding it=
|
|
||||||
Pillager=
|
|
|
@ -87,11 +87,11 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
swap_y_with_x = false,
|
swap_y_with_x = false,
|
||||||
reverse_head_yaw = false,
|
reverse_head_yaw = false,
|
||||||
|
|
||||||
head_bone_pos_y = 0,
|
head_bone_pos_y = 3.6,
|
||||||
head_bone_pos_z = 0,
|
head_bone_pos_z = -0.6,
|
||||||
|
|
||||||
head_height_offset = 1.2,
|
head_height_offset = 1.0525,
|
||||||
head_direction_offset = 0,
|
head_direction_offset = 0.5,
|
||||||
head_pitch_modifier = 0,
|
head_pitch_modifier = 0,
|
||||||
--end head code
|
--end head code
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
},
|
},
|
||||||
animation = {
|
animation = {
|
||||||
speed_normal = 25, run_speed = 65,
|
speed_normal = 25, run_speed = 65,
|
||||||
stand_start = 0, stand_end = 0,
|
stand_start = 40, stand_end = 80,
|
||||||
walk_start = 0, walk_end = 40,
|
walk_start = 0, walk_end = 40,
|
||||||
run_start = 0, run_end = 40,
|
run_start = 0, run_end = 40,
|
||||||
},
|
},
|
||||||
|
@ -330,24 +330,6 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_spawn = function(self)
|
|
||||||
if self.baby then
|
|
||||||
self.animation = table.copy(self.animation)
|
|
||||||
self.animation.stand_start = 81
|
|
||||||
self.animation.stand_end = 81
|
|
||||||
self.animation.walk_start = 81
|
|
||||||
self.animation.walk_end = 121
|
|
||||||
self.animation.run_start = 81
|
|
||||||
self.animation.run_end = 121
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end,
|
|
||||||
on_grown = function(self)
|
|
||||||
self.animation = nil
|
|
||||||
local anim = self.current_animation
|
|
||||||
self.current_animation = nil -- Mobs Redo does nothing otherwise
|
|
||||||
mobs.set_mob_animation(self, anim)
|
|
||||||
end
|
|
||||||
})
|
})
|
||||||
mobs:spawn_specific(
|
mobs:spawn_specific(
|
||||||
"mobs_mc:sheep",
|
"mobs_mc:sheep",
|
||||||
|
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -61,10 +61,38 @@ if minetest.get_mapgen_setting("mg_name") == "v6" then
|
||||||
TRADE_V6_BIRCH_SAPLING = { { "mcl_core:emerald", 8, 11 }, { "mcl_core:birchsapling", 1, 1 } }
|
TRADE_V6_BIRCH_SAPLING = { { "mcl_core:emerald", 8, 11 }, { "mcl_core:birchsapling", 1, 1 } }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local tiernames = {
|
||||||
|
"Novice",
|
||||||
|
"Apprentice",
|
||||||
|
"Journeyman",
|
||||||
|
"Expert",
|
||||||
|
"Master",
|
||||||
|
}
|
||||||
|
|
||||||
|
local badges = {
|
||||||
|
"mcl_core:wood",
|
||||||
|
"mcl_core:stone",
|
||||||
|
"mcl_core:goldblock",
|
||||||
|
"mcl_core:emeraldblock",
|
||||||
|
"mcl_core:diamondblock",
|
||||||
|
}
|
||||||
|
|
||||||
local professions = {
|
local professions = {
|
||||||
|
unemployed = {
|
||||||
|
name = N("Unemployed"),
|
||||||
|
textures = {
|
||||||
|
"mobs_mc_villager.png",
|
||||||
|
"mobs_mc_villager.png",
|
||||||
|
},
|
||||||
|
trades = nil,
|
||||||
|
},
|
||||||
farmer = {
|
farmer = {
|
||||||
name = N("Farmer"),
|
name = N("Farmer"),
|
||||||
texture = "mobs_mc_villager_farmer.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_composters:composter",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_farming:wheat_item", 18, 22, }, E1 },
|
{ { "mcl_farming:wheat_item", 18, 22, }, E1 },
|
||||||
|
@ -76,16 +104,19 @@ local professions = {
|
||||||
{
|
{
|
||||||
{ { "mcl_farming:pumpkin_face", 8, 13 }, E1 },
|
{ { "mcl_farming:pumpkin_face", 8, 13 }, E1 },
|
||||||
{ E1, { "mcl_farming:pumpkin_pie", 2, 3} },
|
{ E1, { "mcl_farming:pumpkin_pie", 2, 3} },
|
||||||
|
{ E1, { "mcl_core:apple", 2, 3} },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_farming:melon", 7, 12 }, E1 },
|
{ { "mcl_farming:melon", 7, 12 }, E1 },
|
||||||
{ E1, { "mcl_core:apple", 5, 7 }, },
|
{ E1, {"mcl_farming:cookie", 5, 7 }, },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ E1, { "mcl_farming:cookie", 6, 10 } },
|
{ E1, { "mcl_mushrooms:mushroom_stew", 6, 10 } }, --FIXME: expert level farmer is supposed to sell sus stews.
|
||||||
{ E1, { "mcl_cake:cake", 1, 1 } },
|
},
|
||||||
|
{
|
||||||
|
{ E1, { "mcl_farming:carrot_item_gold", 3, 10 } },
|
||||||
|
{ E1, { "mcl_potions:speckled_melon", 4, 1 } },
|
||||||
TRADE_V6_BIRCH_SAPLING,
|
TRADE_V6_BIRCH_SAPLING,
|
||||||
TRADE_V6_DARK_OAK_SAPLING,
|
TRADE_V6_DARK_OAK_SAPLING,
|
||||||
TRADE_V6_ACACIA_SAPLING,
|
TRADE_V6_ACACIA_SAPLING,
|
||||||
|
@ -94,33 +125,91 @@ local professions = {
|
||||||
},
|
},
|
||||||
fisherman = {
|
fisherman = {
|
||||||
name = N("Fisherman"),
|
name = N("Fisherman"),
|
||||||
texture = "mobs_mc_villager_farmer.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_chests:barrel",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_fishing:fish_raw", 6, 6, "mcl_core:emerald", 1, 1 }, { "mcl_fishing:fish_cooked", 6, 6 } },
|
{ { "mcl_fishing:fish_raw", 6, 6, "mcl_core:emerald", 1, 1 },{ "mcl_fishing:fish_cooked", 6, 6 } },
|
||||||
{ { "mcl_mobitems:string", 15, 20 }, E1 },
|
{ { "mcl_mobitems:string", 15, 20 }, E1 },
|
||||||
{ { "mcl_core:emerald", 3, 11 }, { "mcl_fishing:fishing_rod_enchanted", 1, 1} },
|
{ { "mcl_core:coal_lump", 15, 10 }, E1 },
|
||||||
|
-- FIXME missing: bucket of cod + fish should be cod.
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_fishing:fish_raw", 6, 15,}, E1 },
|
||||||
|
{ { "mcl_fishing:salmon_raw", 6, 6, "mcl_core:emerald", 1, 1 },{ "mcl_fishing:salmon_cooked", 6, 6 } },
|
||||||
|
-- FIXME missing campfire
|
||||||
|
-- {{ "mcl_core:emerald", 1, 2 },{"mcl_campfires:campfire",1,1} },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_fishing:salmon_raw", 6, 13,}, E1 },
|
||||||
|
{ { "mcl_core:emerald", 7, 22 }, { "mcl_fishing:fishing_rod_enchanted", 1, 1} },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_fishing:clownfish_raw", 6, 6,}, E1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_fishing:pufferfish_raw", 4, 4,}, E1 },
|
||||||
|
|
||||||
|
{ { "mcl_boats:boat", 1, 1,}, E1 },
|
||||||
|
{ { "mcl_boats:boat_acacia", 1, 1,}, E1 },
|
||||||
|
{ { "mcl_boats:boat_spruce", 1, 1,}, E1 },
|
||||||
|
{ { "mcl_boats:boat_dark_oak", 1, 1,}, E1 },
|
||||||
|
{ { "mcl_boats:boat_birch", 1, 1,}, E1 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fletcher = {
|
fletcher = {
|
||||||
name = N("Fletcher"),
|
name = N("Fletcher"),
|
||||||
texture = "mobs_mc_villager_farmer.png",
|
texture = {
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_fletching_table:fletching_table",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_mobitems:string", 15, 20 }, E1 },
|
{ { "mcl_mobitems:string", 15, 20 }, E1 },
|
||||||
{ E1, { "mcl_bows:arrow", 8, 12 } },
|
{ E1, { "mcl_bows:arrow", 8, 12 } },
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ { "mcl_core:gravel", 10, 10, "mcl_core:emerald", 1, 1 }, { "mcl_core:flint", 6, 10 } },
|
{ { "mcl_core:gravel", 10, 10, "mcl_core:emerald", 1, 1 }, { "mcl_core:flint", 6, 10 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_core:flint", 26, 26 }, E1 },
|
||||||
{ { "mcl_core:emerald", 2, 3 }, { "mcl_bows:bow", 1, 1 } },
|
{ { "mcl_core:emerald", 2, 3 }, { "mcl_bows:bow", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_mobitems:string", 14, 14 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 3, 3 }, { "mcl_bows:crossbow", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_mobitems:string", 24, 24 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 7, 21 } , { "mcl_bows:bow_enchanted", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
--FIXME: supposed to be tripwire hook{ { "tripwirehook", 24, 24 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 8, 22 } , { "mcl_bows:crossbow_enchanted", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:healing_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:harming_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:night_vision_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:swiftness_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:slowness_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:leaping_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:poison_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:regeneration_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:invisibility_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:water_breathing_arrow", 5, 5 } },
|
||||||
|
{ { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:fire_resistance_arrow", 5, 5 } },
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shepherd ={
|
shepherd ={
|
||||||
name = N("Shepherd"),
|
name = N("Shepherd"),
|
||||||
texture = "mobs_mc_villager_farmer.png",
|
texture = {
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
"mobs_mc_villager_farmer.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_loom:loom",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_wool:white", 16, 22 }, E1 },
|
{ { "mcl_wool:white", 16, 22 }, E1 },
|
||||||
|
@ -149,180 +238,287 @@ local professions = {
|
||||||
},
|
},
|
||||||
librarian = {
|
librarian = {
|
||||||
name = N("Librarian"),
|
name = N("Librarian"),
|
||||||
texture = "mobs_mc_villager_librarian.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_librarian.png",
|
||||||
|
"mobs_mc_villager_librarian.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_villages:stonebrickcarved", --FIXME: lectern
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_core:paper", 24, 36 }, E1 },
|
{ { "mcl_core:paper", 24, 36 }, E1 },
|
||||||
{ { "mcl_books:book", 8, 10 }, E1 },
|
{ { "mcl_books:book", 8, 10 }, E1 },
|
||||||
{ { "mcl_core:emerald", 10, 12 }, { "mcl_compass:compass", 1 ,1 }},
|
{ { "mcl_core:emerald", 9, 9 }, { "mcl_books:bookshelf", 1 ,1 }},
|
||||||
{ { "mcl_core:emerald", 3, 4 }, { "mcl_books:bookshelf", 1 ,1 }},
|
{ { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
||||||
{ { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_books:written_book", 2, 2 }, E1 },
|
{ { "mcl_books:written_book", 2, 2 }, E1 },
|
||||||
{ { "mcl_core:emerald", 10, 12 }, { "mcl_clock:clock", 1, 1 } },
|
{ { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
||||||
{ E1, { "mcl_core:glass", 3, 5 } },
|
{ E1, { "mcl_lanterns:lantern_floor", 1, 1 } },
|
||||||
{ { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ E1, { "mcl_core:glass", 3, 5 } },
|
{ { "mcl_dye:black", 5, 5 }, E1 },
|
||||||
{ { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
{ { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
||||||
|
{ E1, { "mcl_core:glass", 4, 4 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
{ E1, { "mcl_books:writable_book", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }},
|
||||||
|
{ { "mcl_core:emerald", 4, 4 }, { "mcl_compass:compass", 1 ,1 }},
|
||||||
|
{ { "mcl_core:emerald", 5, 5 }, { "mcl_clock:clock", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:emerald", 20, 22 }, { "mcl_mobs:nametag", 1, 1 } },
|
{ { "mcl_core:emerald", 20, 20 }, { "mcl_mobs:nametag", 1, 1 } },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
cartographer = {
|
cartographer = {
|
||||||
name = N("Cartographer"),
|
name = N("Cartographer"),
|
||||||
texture = "mobs_mc_villager_librarian.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_librarian.png",
|
||||||
|
"mobs_mc_villager_librarian.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_cartography_table:cartography_table",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_core:paper", 24, 36 }, E1 },
|
{ { "mcl_core:paper", 24, 24 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_maps:empty_map", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
-- compass subject to special checks
|
||||||
|
{ { "xpanes:pane_natural_flat", 1, 1 }, E1 },
|
||||||
|
--{ { "mcl_core:emerald", 13, 13, "mcl_compass:compass", 1, 1 }, { "FIXME:ocean explorer map" 1, 1} },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
-- subject to special checks
|
|
||||||
{ { "mcl_compass:compass", 1, 1 }, E1 },
|
{ { "mcl_compass:compass", 1, 1 }, E1 },
|
||||||
|
--{ { "mcl_core:emerald", 13, 13, "mcl_compass:compass", 1, 1 }, { "FIXME:woodland explorer map" 1, 1} },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
-- TODO: replace with empty map
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_itemframes:item_frame", 1, 1 }},
|
||||||
{ { "mcl_core:emerald", 7, 11}, { "mcl_maps:empty_map", 1, 1 } },
|
|
||||||
},
|
|
||||||
|
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_white", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_grey", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_silver", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_black", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_red", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_green", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_cyan", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_blue", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_magenta", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_orange", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_purple", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_brown", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_pink", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_lime", 1, 1 }},
|
||||||
|
{ { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_light_blue", 1, 1 }},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
--{ { "mcl_core:emerald", 8, 8}, { "FIXME: globe banner pattern", 1, 1 } },
|
||||||
|
},
|
||||||
-- TODO: special maps
|
-- TODO: special maps
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
armorer = {
|
armorer = {
|
||||||
name = N("Armorer"),
|
name = N("Armorer"),
|
||||||
texture = "mobs_mc_villager_smith.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_smith.png",
|
||||||
|
"mobs_mc_villager_smith.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_blast_furnace:blast_furnace",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_core:coal_lump", 16, 24 }, E1 },
|
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||||
{ { "mcl_core:emerald", 4, 6 }, { "mcl_armor:helmet_iron", 1, 1 } },
|
{ { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_iron", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 9, 9 }, { "mcl_armor:chestplate_iron", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 7, 7 }, { "mcl_armor:leggings_iron", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 4, 4 }, { "mcl_armor:boots_iron", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:iron_ingot", 7, 9 }, E1 },
|
{ { "mcl_core:iron_ingot", 4, 4 }, E1 },
|
||||||
{ { "mcl_core:emerald", 10, 14 }, { "mcl_armor:chestplate_iron", 1, 1 } },
|
--{ { "mcl_core:emerald", 36, 36 }, { "FIXME: Bell", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 3, 3 }, { "mcl_armor:leggings_chain", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 1, 1 }, { "mcl_armor:boots_chain", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_buckets:bucket_lava", 1, 1 }, E1 },
|
||||||
|
{ { "mcl_core:diamond", 1, 1 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 1, 1 }, { "mcl_armor:helmet_chain", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 4, 4 }, { "mcl_armor:chestplate_chain", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 5, 5 }, { "mcl_shields:shield", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:diamond", 3, 4 }, E1 },
|
{ { "mcl_core:emerald", 19, 33 }, { "mcl_armor:leggings_diamond_enchanted", 1, 1 } },
|
||||||
{ { "mcl_core:emerald", 16, 19 }, { "mcl_armor:chestplate_diamond_enchanted", 1, 1 } },
|
{ { "mcl_core:emerald", 13, 27 }, { "mcl_armor:boots_diamond_enchanted", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:emerald", 5, 7 }, { "mcl_armor:boots_chain", 1, 1 } },
|
{ { "mcl_core:emerald", 13, 27 }, { "mcl_armor:helmet_diamond_enchanted", 1, 1 } },
|
||||||
{ { "mcl_core:emerald", 9, 11 }, { "mcl_armor:leggings_chain", 1, 1 } },
|
{ { "mcl_core:emerald", 21, 35 }, { "mcl_armor:chestplate_diamond_enchanted", 1, 1 } },
|
||||||
{ { "mcl_core:emerald", 5, 7 }, { "mcl_armor:helmet_chain", 1, 1 } },
|
|
||||||
{ { "mcl_core:emerald", 11, 15 }, { "mcl_armor:chestplate_chain", 1, 1 } },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
leatherworker = {
|
leatherworker = {
|
||||||
name = N("Leatherworker"),
|
name = N("Leatherworker"),
|
||||||
texture = "mobs_mc_villager_butcher.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_butcher.png",
|
||||||
|
"mobs_mc_villager_butcher.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_cauldrons:cauldron",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_mobitems:leather", 9, 12 }, E1 },
|
{ { "mcl_mobitems:leather", 9, 12 }, E1 },
|
||||||
{ { "mcl_core:emerald", 2, 4 }, { "mcl_armor:leggings_leather", 2, 4 } },
|
{ { "mcl_core:emerald", 3, 3 }, { "mcl_armor:leggings_leather", 2, 4 } },
|
||||||
|
{ { "mcl_core:emerald", 7, 7 }, { "mcl_armor:chestplate_leather", 2, 4 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:emerald", 7, 12 }, { "mcl_armor:chestplate_leather_enchanted", 1, 1 } },
|
{ { "mcl_core:flint", 26, 26 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_leather", 2, 4 } },
|
||||||
|
{ { "mcl_core:emerald", 4, 4 }, { "mcl_armor:boots_leather", 2, 4 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
{ { "mcl_mobitems:rabbit_hide", 9, 9 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 7, 7 }, { "mcl_armor:chestplate_leather", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
--{ { "FIXME: scute", 4, 4 }, E1 },
|
||||||
{ { "mcl_core:emerald", 8, 10 }, { "mcl_mobitems:saddle", 1, 1 } },
|
{ { "mcl_core:emerald", 8, 10 }, { "mcl_mobitems:saddle", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_core:emerald", 6, 6 }, { "mcl_mobitems:saddle", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_leather", 2, 4 } },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
butcher = {
|
butcher = {
|
||||||
name = N("Butcher"),
|
name = N("Butcher"),
|
||||||
texture = "mobs_mc_villager_butcher.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_butcher.png",
|
||||||
|
"mobs_mc_villager_butcher.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_smoker:smoker",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_mobitems:beef", 14, 18 }, E1 },
|
{ { "mcl_mobitems:beef", 14, 14 }, E1 },
|
||||||
{ { "mcl_mobitems:chicken", 14, 18 }, E1 },
|
{ { "mcl_mobitems:chicken", 7, 7 }, E1 },
|
||||||
|
{ { "mcl_mobitems:rabbit", 4, 4 }, E1 },
|
||||||
|
{ E1, { "mcl_mobitems:rabbit_stew", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:coal_lump", 16, 24 }, E1 },
|
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||||
{ E1, { "mcl_mobitems:cooked_beef", 5, 7 } },
|
{ E1, { "mcl_mobitems:cooked_porkchop", 5, 5 } },
|
||||||
{ E1, { "mcl_mobitems:cooked_chicken", 6, 8 } },
|
{ E1, { "mcl_mobitems:cooked_chicken", 8, 8 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_mobitems:mutton", 7, 7 }, E1 },
|
||||||
|
{ { "mcl_mobitems:beef", 10, 10 }, E1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_mobitems:mutton", 7, 7 }, E1 },
|
||||||
|
{ { "mcl_mobitems:beef", 10, 10 }, E1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
--{ { "FIXME: Sweet Berries", 10, 10 }, E1 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
weapon_smith = {
|
weapon_smith = {
|
||||||
name = N("Weapon Smith"),
|
name = N("Weapon Smith"),
|
||||||
texture = "mobs_mc_villager_smith.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_smith.png",
|
||||||
|
"mobs_mc_villager_smith.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_villages:stonebrickcarved", --FIXME: grindstone
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_core:coal_lump", 16, 24 }, E1 },
|
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||||
{ { "mcl_core:emerald", 6, 8 }, { "mcl_tools:axe_iron", 1, 1 } },
|
{ { "mcl_core:emerald", 3, 3 }, { "mcl_tools:axe_iron", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 7, 21 }, { "mcl_tools:sword_iron_enchanted", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:iron_ingot", 7, 9 }, E1 },
|
{ { "mcl_core:iron_ingot", 4, 4 }, E1 },
|
||||||
{ { "mcl_core:emerald", 9, 10 }, { "mcl_tools:sword_iron_enchanted", 1, 1 } },
|
--{ { "mcl_core:emerald", 36, 36 }, { "FIXME: Bell", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_core:flint", 7, 9 }, E1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_core:diamond", 7, 9 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 17, 31 }, { "mcl_tools:axe_diamond_enchanted", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:diamond", 3, 4 }, E1 },
|
{ { "mcl_core:emerald", 13, 27 }, { "mcl_tools:sword_diamond_enchanted", 1, 1 } },
|
||||||
{ { "mcl_core:emerald", 12, 15 }, { "mcl_tools:sword_diamond_enchanted", 1, 1 } },
|
|
||||||
{ { "mcl_core:emerald", 9, 12 }, { "mcl_tools:axe_diamond_enchanted", 1, 1 } },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tool_smith = {
|
tool_smith = {
|
||||||
name = N("Tool Smith"),
|
name = N("Tool Smith"),
|
||||||
texture = "mobs_mc_villager_smith.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_smith.png",
|
||||||
|
"mobs_mc_villager_smith.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_anvils:anvil", --FIXME: smithing table
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_core:coal_lump", 16, 24 }, E1 },
|
{ { "mcl_core:coal_lump", 15, 15 }, E1 },
|
||||||
{ { "mcl_core:emerald", 5, 7 }, { "mcl_tools:shovel_iron_enchanted", 1, 1 } },
|
{ E1, { "mcl_tools:axe_stone", 1, 1 } },
|
||||||
|
{ E1, { "mcl_tools:shovel_stone", 1, 1 } },
|
||||||
|
{ E1, { "mcl_tools:pick_stone", 1, 1 } },
|
||||||
|
{ E1, { "mcl_farming:hoe_stone", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:iron_ingot", 7, 9 }, E1 },
|
{ { "mcl_core:iron_ingot", 4, 4 }, E1 },
|
||||||
{ { "mcl_core:emerald", 9, 11 }, { "mcl_tools:pick_iron_enchanted", 1, 1 } },
|
--{ { "mcl_core:emerald", 36, 36 }, { "FIXME: Bell", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_core:diamond", 3, 4 }, E1 },
|
{ { "mcl_core:flint", 30, 30 }, E1 },
|
||||||
{ { "mcl_core:emerald", 12, 15 }, { "mcl_tools:pick_diamond_enchanted", 1, 1 } },
|
{ { "mcl_core:emerald", 6, 20 }, { "mcl_tools:axe_iron_enchanted", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 7, 21 }, { "mcl_tools:shovel_iron_enchanted", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 8, 22 }, { "mcl_tools:pick_iron_enchanted", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 4, 4 }, { "mcl_farming:hoe_diamond", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_core:diamond", 1, 1 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 17, 31 }, { "mcl_tools:axe_diamond_enchanted", 1, 1 } },
|
||||||
|
{ { "mcl_core:emerald", 10, 24 }, { "mcl_tools:shovel_diamond_enchanted", 1, 1 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ { "mcl_core:emerald", 18, 32 }, { "mcl_tools:pick_diamond_enchanted", 1, 1 } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
cleric = {
|
cleric = {
|
||||||
name = N("Cleric"),
|
name = N("Cleric"),
|
||||||
texture = "mobs_mc_villager_priest.png",
|
textures = {
|
||||||
|
"mobs_mc_villager_priest.png",
|
||||||
|
"mobs_mc_villager_priest.png",
|
||||||
|
},
|
||||||
|
jobsite = "mcl_brewing:stand_000",
|
||||||
trades = {
|
trades = {
|
||||||
{
|
{
|
||||||
{ { "mcl_mobitems:rotten_flesh", 36, 40 }, E1 },
|
{ { "mcl_mobitems:rotten_flesh", 32, 32 }, E1 },
|
||||||
{ { "mcl_core:gold_ingot", 8, 10 }, E1 },
|
{ E1, { "mesecons:redstone", 2, 2 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ E1, { "mesecons:redstone", 1, 4 } },
|
{ { "mcl_core:gold_ingot", 3, 3 }, E1 },
|
||||||
{ E1, { "mcl_dye:blue", 1, 2 } },
|
{ E1, { "mcl_dye:blue", 1, 1 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ E1, { "mcl_nether:glowstone", 1, 3 } },
|
{ { "mcl_mobitems:rabbit_foot", 2, 2 }, E1 },
|
||||||
{ { "mcl_core:emerald", 4, 7 }, { "mcl_throwing:ender_pearl", 1, 1 } },
|
{ E1, { "mcl_nether:glowstone", 4, 4 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
--{ { "FIXME: scute", 4, 4 }, E1 },
|
||||||
|
{ { "mcl_potions:glass_bottle", 9, 9 }, E1 },
|
||||||
|
{ { "mcl_core:emerald", 5, 5 }, { "mcl_throwing:ender_pearl", 1, 1 } },
|
||||||
TRADE_V6_RED_SANDSTONE,
|
TRADE_V6_RED_SANDSTONE,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{ { "mcl_nether:nether_wart_item", 22, 22 }, E1 },
|
{ { "mcl_nether:nether_wart_item", 22, 22 }, E1 },
|
||||||
{ { "mcl_core:emerald", 3, 3 }, { "mcl_experience:bottle", 1, 1 } },
|
{ { "mcl_core:emerald", 3, 3 }, { "mcl_experience:bottle", 1, 1 } },
|
||||||
|
@ -331,7 +527,10 @@ local professions = {
|
||||||
},
|
},
|
||||||
nitwit = {
|
nitwit = {
|
||||||
name = N("Nitwit"),
|
name = N("Nitwit"),
|
||||||
texture = "mobs_mc_villager.png",
|
textures = {
|
||||||
|
"mobs_mc_villager.png",
|
||||||
|
"mobs_mc_villager.png",
|
||||||
|
},
|
||||||
-- No trades for nitwit
|
-- No trades for nitwit
|
||||||
trades = nil,
|
trades = nil,
|
||||||
}
|
}
|
||||||
|
@ -342,11 +541,110 @@ for id, _ in pairs(professions) do
|
||||||
table.insert(profession_names, id)
|
table.insert(profession_names, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local jobsites={}
|
||||||
|
for _,n in pairs(profession_names) do
|
||||||
|
table.insert(jobsites,professions[n].jobsite)
|
||||||
|
end
|
||||||
|
|
||||||
local stand_still = function(self)
|
local stand_still = function(self)
|
||||||
self.walk_chance = 0
|
self.walk_chance = 0
|
||||||
self.jump = false
|
self.jump = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function init_trader_vars(self)
|
||||||
|
if not self._max_trade_tier then
|
||||||
|
self._max_trade_tier = 1
|
||||||
|
end
|
||||||
|
if not self._locked_trades then
|
||||||
|
self._locked_trades = 0
|
||||||
|
end
|
||||||
|
if not self._trading_players then
|
||||||
|
self._trading_players = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
----- JOBSITE LOGIC
|
||||||
|
|
||||||
|
local function set_velocity(self, v)
|
||||||
|
local yaw = (self.object:get_yaw() or 0) + self.rotate
|
||||||
|
self.object:set_velocity({
|
||||||
|
x = (math.sin(yaw) * -v),
|
||||||
|
y = self.object:get_velocity().y,
|
||||||
|
z = (math.cos(yaw) * v),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function go_to_pos(entity,b)
|
||||||
|
local s=entity.object:get_pos()
|
||||||
|
if vector.distance(b,s) < 1 then
|
||||||
|
--set_velocity(entity,0)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local v = { x = b.x - s.x, z = b.z - s.z }
|
||||||
|
local yaw = (math.atan(v.z / v.x) + math.pi / 2) - entity.rotate
|
||||||
|
if b.x > s.x then yaw = yaw + math.pi end
|
||||||
|
entity.object:set_yaw(yaw)
|
||||||
|
set_velocity(entity,entity.follow_velocity)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function go_home(entity)
|
||||||
|
entity.state = "go_home"
|
||||||
|
local b=entity.bed
|
||||||
|
if not b then return end
|
||||||
|
if go_to_pos(entity,b) then
|
||||||
|
entity.state = "stand"
|
||||||
|
set_velocity(entity,0)
|
||||||
|
entity.object:set_pos(b)
|
||||||
|
local n=minetest.get_node(b)
|
||||||
|
if n and n.name ~= "mcl_beds:bed_red_bottom" then
|
||||||
|
entity.bed=nil --the stormtroopers have killed uncle owen
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_profession_by_jobsite(js)
|
||||||
|
for k,v in pairs(professions) do
|
||||||
|
if v.jobsite == js then return k end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function employ(self,jobsite_pos)
|
||||||
|
local n = minetest.get_node(jobsite_pos)
|
||||||
|
local m = minetest.get_meta(jobsite_pos)
|
||||||
|
local p = get_profession_by_jobsite(n.name)
|
||||||
|
if p and m:get_string("villager") == "" then
|
||||||
|
self._profession=p
|
||||||
|
m:set_string("villager",self._id)
|
||||||
|
self._jobsite = jobsite_pos
|
||||||
|
self.object:set_properties({textures=professions[self._profession].textures})
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function unemploy(self)
|
||||||
|
self._profession="unemployed"
|
||||||
|
self._jobsite = nil
|
||||||
|
self.object:set_properties({textures=professions[self._profession].textures})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_a_job(self)
|
||||||
|
local p = self.object:get_pos()
|
||||||
|
local nn = minetest.find_nodes_in_area(vector.offset(p,-8,-8,-8),vector.offset(p,8,8,8),jobsites)
|
||||||
|
for _,n in pairs(nn) do
|
||||||
|
if n and employ(self,n) then return end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function check_jobsite(self)
|
||||||
|
local n = minetest.get_node(self._jobsite)
|
||||||
|
local m = minetest.get_meta(self._jobsite)
|
||||||
|
if n.name ~= professions[self._profession].jobsite or m:get_string("villager") ~= self._id then
|
||||||
|
unemploy(self)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
local update_max_tradenum = function(self)
|
local update_max_tradenum = function(self)
|
||||||
if not self._trades then
|
if not self._trades then
|
||||||
return
|
return
|
||||||
|
@ -362,30 +660,6 @@ local update_max_tradenum = function(self)
|
||||||
self._max_tradenum = #trades
|
self._max_tradenum = #trades
|
||||||
end
|
end
|
||||||
|
|
||||||
local init_trader_vars = function(self)
|
|
||||||
if not self._profession then
|
|
||||||
-- Select random profession from all professions with matching clothing
|
|
||||||
local texture = self.base_texture[1]
|
|
||||||
local matches = {}
|
|
||||||
for prof_id, prof in pairs(professions) do
|
|
||||||
if texture == prof.texture then
|
|
||||||
table.insert(matches, prof_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local p = math.random(1, #matches)
|
|
||||||
self._profession = matches[p]
|
|
||||||
end
|
|
||||||
if not self._max_trade_tier then
|
|
||||||
self._max_trade_tier = 1
|
|
||||||
end
|
|
||||||
if not self._locked_trades then
|
|
||||||
self._locked_trades = 0
|
|
||||||
end
|
|
||||||
if not self._trading_players then
|
|
||||||
self._trading_players = {}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local init_trades = function(self, inv)
|
local init_trades = function(self, inv)
|
||||||
local profession = professions[self._profession]
|
local profession = professions[self._profession]
|
||||||
local trade_tiers = profession and profession.trades
|
local trade_tiers = profession and profession.trades
|
||||||
|
@ -516,7 +790,7 @@ local function show_trade_formspec(playername, trader, tradenum)
|
||||||
"size[9,8.75]"
|
"size[9,8.75]"
|
||||||
.."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]"
|
.."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]"
|
||||||
..disabled_img
|
..disabled_img
|
||||||
.."label[4,0;"..F(minetest.colorize("#313131", S(profession))).."]"
|
.."label[3,0;"..F(minetest.colorize("#313131", S(profession).." - "..S(tiernames[trader._max_trade_tier]))) .."]"
|
||||||
.."list[current_player;main;0,4.5;9,3;9]"
|
.."list[current_player;main;0,4.5;9,3;9]"
|
||||||
.."list[current_player;main;0,7.74;9,1;]"
|
.."list[current_player;main;0,7.74;9,1;]"
|
||||||
..b_prev..b_next
|
..b_prev..b_next
|
||||||
|
@ -941,31 +1215,9 @@ mobs:register_mob("mobs_mc:villager", {
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_villager.b3d",
|
mesh = "mobs_mc_villager.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
{
|
|
||||||
"mobs_mc_villager.png",
|
"mobs_mc_villager.png",
|
||||||
"mobs_mc_villager.png", --hat
|
"mobs_mc_villager.png", --hat
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"mobs_mc_villager_farmer.png",
|
|
||||||
"mobs_mc_villager_farmer.png", --hat
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mobs_mc_villager_priest.png",
|
|
||||||
"mobs_mc_villager_priest.png", --hat
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mobs_mc_villager_librarian.png",
|
|
||||||
"mobs_mc_villager_librarian.png", --hat
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mobs_mc_villager_butcher.png",
|
|
||||||
"mobs_mc_villager_butcher.png", --hat
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mobs_mc_villager_smith.png",
|
|
||||||
"mobs_mc_villager_smith.png", --hat
|
|
||||||
},
|
|
||||||
},
|
|
||||||
visual_size = {x=2.75, y=2.75},
|
visual_size = {x=2.75, y=2.75},
|
||||||
rotate = 270,
|
rotate = 270,
|
||||||
skittish = true,
|
skittish = true,
|
||||||
|
@ -1000,12 +1252,35 @@ mobs:register_mob("mobs_mc:villager", {
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
jump = true,
|
jump = true,
|
||||||
walk_chance = DEFAULT_WALK_CHANCE,
|
walk_chance = DEFAULT_WALK_CHANCE,
|
||||||
|
bed = nil,
|
||||||
|
_id = nil,
|
||||||
|
_profession = "unemployed",
|
||||||
|
look_at_player = true,
|
||||||
|
pick_up = {"mcl_farming:bread"},
|
||||||
|
on_pick_up = function(self,itementity)
|
||||||
|
local clicker
|
||||||
|
for _,p in pairs(minetest.get_connected_players()) do
|
||||||
|
if vector.distance(p:get_pos(),self.object:get_pos()) < 10 then
|
||||||
|
clicker = p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not clicker then minetest.log("no clicker") end
|
||||||
|
if clicker then
|
||||||
|
mobs:feed_tame(self, clicker, 1, true, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
return true --do not pick up
|
||||||
|
end,
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
|
end
|
||||||
|
if self.child or self._profession == "unemployed" then
|
||||||
|
return
|
||||||
|
end
|
||||||
-- Initiate trading
|
-- Initiate trading
|
||||||
|
--init_trader_vars(self)
|
||||||
local name = clicker:get_player_name()
|
local name = clicker:get_player_name()
|
||||||
self._trading_players[name] = true
|
self._trading_players[name] = true
|
||||||
|
|
||||||
init_trader_vars(self)
|
|
||||||
if self._trades == nil then
|
if self._trades == nil then
|
||||||
init_trades(self)
|
init_trades(self)
|
||||||
end
|
end
|
||||||
|
@ -1042,6 +1317,7 @@ mobs:register_mob("mobs_mc:villager", {
|
||||||
if not self._player_scan_timer then
|
if not self._player_scan_timer then
|
||||||
self._player_scan_timer = 0
|
self._player_scan_timer = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
self._player_scan_timer = self._player_scan_timer + dtime
|
self._player_scan_timer = self._player_scan_timer + dtime
|
||||||
-- Check infrequently to keep CPU load low
|
-- Check infrequently to keep CPU load low
|
||||||
if self._player_scan_timer > PLAYER_SCAN_INTERVAL then
|
if self._player_scan_timer > PLAYER_SCAN_INTERVAL then
|
||||||
|
@ -1063,20 +1339,36 @@ mobs:register_mob("mobs_mc:villager", {
|
||||||
self.walk_chance = DEFAULT_WALK_CHANCE
|
self.walk_chance = DEFAULT_WALK_CHANCE
|
||||||
self.jump = true
|
self.jump = true
|
||||||
end
|
end
|
||||||
|
if self.bed and ( self.state == "go_home" or vector.distance(self.object:get_pos(),self.bed) > 50 ) then
|
||||||
|
go_home(self)
|
||||||
|
end
|
||||||
|
if self._profession == "unemployed" then
|
||||||
|
get_a_job(self)
|
||||||
|
else
|
||||||
|
check_jobsite(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_spawn = function(self)
|
on_spawn = function(self)
|
||||||
init_trader_vars(self)
|
if self._id then
|
||||||
|
self.object:set_properties({textures=professions[self._profession].textures})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random()))
|
||||||
|
self._profession = "unemployed"
|
||||||
|
self.object:set_properties({textures=professions[self._profession].textures})
|
||||||
end,
|
end,
|
||||||
on_die = function(self, pos)
|
on_die = function(self, pos)
|
||||||
-- Close open trade formspecs and give input back to players
|
-- Close open trade formspecs and give input back to players
|
||||||
local trading_players = self._trading_players
|
local trading_players = self._trading_players
|
||||||
for name, _ in pairs(trading_players) do
|
if trading_players then
|
||||||
minetest.close_formspec(name, "mobs_mc:trade_"..name)
|
for name, _ in pairs(trading_players) do
|
||||||
local player = minetest.get_player_by_name(name)
|
minetest.close_formspec(name, "mobs_mc:trade_"..name)
|
||||||
if player then
|
local player = minetest.get_player_by_name(name)
|
||||||
return_fields(player)
|
if player then
|
||||||
|
return_fields(player)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -229,23 +229,19 @@ mobs_mc.override.spawn = {
|
||||||
}
|
}
|
||||||
|
|
||||||
-- This table contains important spawn height references for the mob spawn height.
|
-- This table contains important spawn height references for the mob spawn height.
|
||||||
local get_local_settings = function()
|
mobs_mc.override.spawn_height = {
|
||||||
mobs_mc.override.spawn_height = {
|
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
|
||||||
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
|
|
||||||
|
|
||||||
-- Overworld boundaries (inclusive)
|
-- Overworld boundaries (inclusive)
|
||||||
overworld_min = mcl_mapgen.overworld.min,
|
overworld_min = mcl_mapgen.overworld.min,
|
||||||
overworld_max = mcl_mapgen.overworld.max,
|
overworld_max = mcl_mapgen.overworld.max,
|
||||||
|
|
||||||
-- Nether boundaries (inclusive)
|
-- Nether boundaries (inclusive)
|
||||||
nether_min = mcl_mapgen.nether.min,
|
nether_min = mcl_mapgen.nether.min,
|
||||||
nether_max = mcl_mapgen.nether.max,
|
nether_max = mcl_mapgen.nether.max,
|
||||||
|
|
||||||
-- End boundaries (inclusive)
|
-- End boundaries (inclusive)
|
||||||
end_min = mcl_mapgen.end_.min,
|
end_min = mcl_mapgen.end_.min,
|
||||||
end_max = mcl_mapgen.end_.max,
|
end_max = mcl_mapgen.end_.max,
|
||||||
}
|
}
|
||||||
end
|
|
||||||
get_local_settings()
|
|
||||||
mcl_mapgen.register_on_settings_changed(get_local_settings)
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
# textdomain: lightning
|
|
||||||
@1 was struck by lightning.=@1 fuguèt pica·t·da per lo tròn
|
|
||||||
Let lightning strike at the specified position or yourself=Pica lo tròn vès una posicion mencionada o sobre vosautr·e·a·s-mema
|
|
||||||
No position specified and unknown player=Pas de posicion mencionada e jogair·e·a pas conegu·t·da
|
|
|
@ -1,4 +1,4 @@
|
||||||
# textdomain: lightning
|
# textdomain: lightning
|
||||||
@1 was struck by lightning.=@1 a été frappé(e) par la foudre.
|
@1 was struck by lightning.=@1 a été frappé(e) par la foudre.
|
||||||
Let lightning strike at the specified position or player. No parameter will strike yourself.=Fait frapper la foudre sur la position ou le joueur indiqué. Sans paramètre, la foudre frappera sur vous-même.
|
Let lightning strike at the specified position or yourself=Fait frapper la foudre à la position spécifiée ou sur vous-même
|
||||||
No position specified and unknown player=Aucune position spécifiée et joueur inconnu
|
No position specified and unknown player=Aucune position spécifiée et joueur inconnu
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# textdomain: mcl_void_damage
|
|
||||||
The void is off-limits to you!=Lo voeida es defendut per vosautr·e·a·s !
|
|
||||||
@1 fell into the endless void.=@1 es tombar dins la voeida infinida.
|
|
|
@ -5,4 +5,4 @@ Error: No weather specified.=Erreur: Aucune météo spécifiée.
|
||||||
Error: Invalid parameters.=Erreur: Paramètres non valides.
|
Error: Invalid parameters.=Erreur: Paramètres non valides.
|
||||||
Error: Duration can't be less than 1 second.=Erreur: La durée ne peut pas être inférieure à 1 seconde.
|
Error: Duration can't be less than 1 second.=Erreur: La durée ne peut pas être inférieure à 1 seconde.
|
||||||
Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=Erreur: Météo non valide spécifiée. Utilisez "clear" (clair), "rain" (pluie), "snow" (neige) ou "thunder" (tonnerre).
|
Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=Erreur: Météo non valide spécifiée. Utilisez "clear" (clair), "rain" (pluie), "snow" (neige) ou "thunder" (tonnerre).
|
||||||
Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=Bascule entre temps clair et temps avec des précipitations (au hasard entre pluie, orage ou neige)
|
Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=Bascule entre temps clair et temps avec chute (au hasard entre pluie, orage ou neige)
|
||||||
|
|
|
@ -611,14 +611,11 @@ do
|
||||||
io.close(file)
|
io.close(file)
|
||||||
if string then
|
if string then
|
||||||
local savetable = minetest.deserialize(string)
|
local savetable = minetest.deserialize(string)
|
||||||
local savetable_players_stored_data = savetable and savetable.players_stored_data
|
for name, players_stored_data in pairs(savetable.players_stored_data) do
|
||||||
if savetable_players_stored_data then
|
doc.data.players[name] = {}
|
||||||
for name, players_stored_data in pairs(savetable_players_stored_data) do
|
doc.data.players[name].stored_data = players_stored_data
|
||||||
doc.data.players[name] = {}
|
|
||||||
doc.data.players[name].stored_data = players_stored_data
|
|
||||||
end
|
|
||||||
minetest.log("action", "[doc] doc.mt successfully read.")
|
|
||||||
end
|
end
|
||||||
|
minetest.log("action", "[doc] doc.mt successfully read.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,6 +17,7 @@ Skeleton view range: -50%=
|
||||||
Creeper view range: -50%=
|
Creeper view range: -50%=
|
||||||
Damage: @1=
|
Damage: @1=
|
||||||
Damage (@1): @2=
|
Damage (@1): @2=
|
||||||
|
Durability: @1
|
||||||
Healing: @1=
|
Healing: @1=
|
||||||
Healing (@1): @2=
|
Healing (@1): @2=
|
||||||
Full punch interval: @1s=
|
Full punch interval: @1s=
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# textdomain: awards
|
# textdomain:awards
|
||||||
@1/@2 chat messages=@1/@2 chat messages
|
@1/@2 chat messages=@1/@2 chat messages
|
||||||
@1/@2 crafted=@1/@2 fabrication
|
@1/@2 crafted=@1/@2 fabrication
|
||||||
@1/@2 deaths=@1/@2 Mort
|
@1/@2 deaths=@1/@2 Mort
|
||||||
|
@ -6,11 +6,12 @@
|
||||||
@1/@2 game joins=@1/@2 sessions
|
@1/@2 game joins=@1/@2 sessions
|
||||||
@1/@2 placed=@1/@2 mis
|
@1/@2 placed=@1/@2 mis
|
||||||
@1 (got)=@1 (obtenu)
|
@1 (got)=@1 (obtenu)
|
||||||
@1: @2=@1: @2
|
@1: @1=@1: @1
|
||||||
@1’s awards:=Récompenses de @1:
|
@1’s awards:=Récompenses de @1:
|
||||||
(Secret Award)=(Récompense Secrètte)
|
(Secret Award)=(Récompense Secrètte)
|
||||||
<achievement ID>=<Succès ID>
|
<achievement ID>=<Succès ID>
|
||||||
<name>=<nom>
|
<name>=<nom>
|
||||||
|
A Cat in a Pop-Tart?!=Un chat beurré ?!
|
||||||
Achievement gotten!=Succès obtenu !
|
Achievement gotten!=Succès obtenu !
|
||||||
Achievement gotten:=Succès obtenu :
|
Achievement gotten:=Succès obtenu :
|
||||||
Achievement gotten: @1=Succès obtenu : @1
|
Achievement gotten: @1=Succès obtenu : @1
|
||||||
|
@ -27,9 +28,9 @@ Join the game.=Rejoignez le jeu.
|
||||||
List awards in chat (deprecated)=Liste des récompenses dans le chat (obsolète)
|
List awards in chat (deprecated)=Liste des récompenses dans le chat (obsolète)
|
||||||
Place a block: @1=Placer un bloc: @1
|
Place a block: @1=Placer un bloc: @1
|
||||||
Place blocks: @1×@2=Placer des blocs: @1×@2
|
Place blocks: @1×@2=Placer des blocs: @1×@2
|
||||||
Secret achievement gotten!=Succès secret obtenu !
|
Secret Achievement gotten!=Succès secret obtenu !
|
||||||
Secret achievement gotten:=Succès secret obtenu :
|
Secret Achievement gotten:=Succès secret obtenu :
|
||||||
Secret achievement gotten: @1=Succès secret obtenu : @1
|
Secret Achievement gotten: @1=Succès secret obtenu : @1
|
||||||
Show details of an achievement=Afficher les détails d'un succès
|
Show details of an achievement=Afficher les détails d'un succès
|
||||||
Show, clear, disable or enable your achievements=Affichez, effacez, désactivez ou activez vos succès
|
Show, clear, disable or enable your achievements=Affichez, effacez, désactivez ou activez vos succès
|
||||||
Get this achievement to find out what it is.=Obtenez ce succès pour découvrir de quoi il s'agit.
|
Get this achievement to find out what it is.=Obtenez ce succès pour découvrir de quoi il s'agit.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# textdomain: awards
|
# textdomain:awards
|
||||||
@1/@2 chat messages=
|
@1/@2 chat messages=
|
||||||
@1/@2 crafted=
|
@1/@2 crafted=
|
||||||
@1/@2 deaths=
|
@1/@2 deaths=
|
||||||
|
|
|
@ -234,20 +234,6 @@ awards.register_achievement("mcl:fishyBusiness", {
|
||||||
icon = "mcl_fishing_fishing_rod.png",
|
icon = "mcl_fishing_fishing_rod.png",
|
||||||
})
|
})
|
||||||
|
|
||||||
--Triggered in mcl_beacons
|
|
||||||
awards.register_achievement("mcl:beacon", {
|
|
||||||
title = S("Bring Home the Beacon"),
|
|
||||||
description = S("Use a beacon."),
|
|
||||||
icon = "beacon_achievement_icon.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_achievement("mcl:maxed_beacon", {
|
|
||||||
title = S("Beaconator"),
|
|
||||||
description = S("Use a fully powered beacon."),
|
|
||||||
icon = "beacon_achievement_icon.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
-- Armor Advancements
|
-- Armor Advancements
|
||||||
--[[awards.register_achievement("mcl:suitUp", {
|
--[[awards.register_achievement("mcl:suitUp", {
|
||||||
title = S("Suit Up"),
|
title = S("Suit Up"),
|
||||||
|
|
|
@ -47,7 +47,3 @@ Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Benutz
|
||||||
Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Benutzen Sie eine Werkbank, um eine Holzspitzhacke aus Holzplanken und Stöcken zu fertigen.
|
Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Benutzen Sie eine Werkbank, um eine Holzspitzhacke aus Holzplanken und Stöcken zu fertigen.
|
||||||
Use obsidian and a fire starter to construct a Nether portal.=Benutzen Sie Obsidian und ein Feuerzeug, um ein Netherportal zu errichten.
|
Use obsidian and a fire starter to construct a Nether portal.=Benutzen Sie Obsidian und ein Feuerzeug, um ein Netherportal zu errichten.
|
||||||
Use wheat to craft a bread.=Benutzen Sie Weizen, um ein Brot zu machen.
|
Use wheat to craft a bread.=Benutzen Sie Weizen, um ein Brot zu machen.
|
||||||
Bring Home the Beacon=Den Nachbarn heimleuchten
|
|
||||||
Use a beacon.=Benutzen Sie ein Leuchtfeuer.
|
|
||||||
Beaconator=Leuchtturmwärter
|
|
||||||
Use a fully powered beacon.=Benutzen Sie ein vollständiges Leuchtfeuer.
|
|
|
@ -63,15 +63,3 @@ Not Quite "Nine" Lives=Presque "neuf" vies
|
||||||
Charge a Respawn Anchor to the maximum.=Charger une Ancre de Réapparition au maximum.
|
Charge a Respawn Anchor to the maximum.=Charger une Ancre de Réapparition au maximum.
|
||||||
The End?=L'End ?
|
The End?=L'End ?
|
||||||
Or the beginning?\nHint: Enter an end portal.=Ou le commencement ?\nAstuce : Entrer dans un portail de l'End.
|
Or the beginning?\nHint: Enter an end portal.=Ou le commencement ?\nAstuce : Entrer dans un portail de l'End.
|
||||||
Postmortal=Aux frontières de la mort
|
|
||||||
Use a Totem of Undying to cheat death.=Utiliser un Totem d'imortalité pour tromper la mort.
|
|
||||||
Sweet Dreams=Bonne nuit les petits
|
|
||||||
Sleep in a bed to change your respawn point.=Dormez dans un lit pour changer votre point de réapparition.
|
|
||||||
Serious Dedication=Sérieux dévouement
|
|
||||||
Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.=Utilisez un lingot de netherite pour améliorez une houe, puis réévaluez complètement vos choix de vie.
|
|
||||||
Fishy Business=Merci pour le poisson
|
|
||||||
Catch a fish. \nHint: Catch a fish, salmon, clownfish, or pufferfish.=Attrapez un poisson. \nAstuce : attrapez un poisson, saumon, poisson-clown, ou poisson-globe.
|
|
||||||
What A Deal!=Adjugé, Vendu !
|
|
||||||
Successfully trade with a Villager.=Commercez avec succès avec un villageois.
|
|
||||||
Tactical Fishing=Pêche tactique
|
|
||||||
Catch a fish... without a fishing rod=Attrapez un poisson... sans canne à pêche
|
|
|
@ -75,7 +75,3 @@ What A Deal!=
|
||||||
Successfully trade with a Villager.=
|
Successfully trade with a Villager.=
|
||||||
Tactical Fishing=
|
Tactical Fishing=
|
||||||
Catch a fish... without a fishing rod=
|
Catch a fish... without a fishing rod=
|
||||||
Bring Home the Beacon=
|
|
||||||
Use a beacon.=
|
|
||||||
Beaconator=
|
|
||||||
Use a fully powered beacon.=
|
|
|
@ -6,7 +6,6 @@ Alexander Minges
|
||||||
aligator
|
aligator
|
||||||
ArTee3
|
ArTee3
|
||||||
Artem Arbatsky
|
Artem Arbatsky
|
||||||
balazsszalab
|
|
||||||
basxto
|
basxto
|
||||||
Benjamin Schötz
|
Benjamin Schötz
|
||||||
Blue Blancmange
|
Blue Blancmange
|
||||||
|
@ -14,7 +13,6 @@ Booglejr
|
||||||
Brandon
|
Brandon
|
||||||
Bu-Gee
|
Bu-Gee
|
||||||
bzoss
|
bzoss
|
||||||
CableGuy67
|
|
||||||
chmodsayshello
|
chmodsayshello
|
||||||
Code-Sploit
|
Code-Sploit
|
||||||
cora
|
cora
|
||||||
|
@ -33,7 +31,6 @@ Emojigit
|
||||||
epCode
|
epCode
|
||||||
erlehmann
|
erlehmann
|
||||||
FinishedFragment
|
FinishedFragment
|
||||||
FlamingRCCars
|
|
||||||
Glaucos Ginez
|
Glaucos Ginez
|
||||||
Gustavo Ramos Rehermann
|
Gustavo Ramos Rehermann
|
||||||
Guy Liner
|
Guy Liner
|
||||||
|
@ -42,7 +39,6 @@ HimbeerserverDE
|
||||||
iliekprogrammar
|
iliekprogrammar
|
||||||
j1233
|
j1233
|
||||||
Jared Moody
|
Jared Moody
|
||||||
Johannes Fritz
|
|
||||||
jordan4ibanez
|
jordan4ibanez
|
||||||
kabou
|
kabou
|
||||||
kay27
|
kay27
|
||||||
|
@ -50,14 +46,13 @@ Laurent Rocher
|
||||||
Li0n
|
Li0n
|
||||||
marcin-serwin
|
marcin-serwin
|
||||||
Marcin Serwin
|
Marcin Serwin
|
||||||
Mark Roth
|
|
||||||
Mental-Inferno
|
Mental-Inferno
|
||||||
Midgard
|
Midgard
|
||||||
MysticTempest
|
MysticTempest
|
||||||
Nicholas Niro
|
Nicholas Niro
|
||||||
nickolas360
|
nickolas360
|
||||||
Nicu
|
Nicu
|
||||||
Niklp
|
nikolaus-albinger
|
||||||
Nils Dagsson Moskopp
|
Nils Dagsson Moskopp
|
||||||
NO11
|
NO11
|
||||||
NO411
|
NO411
|
||||||
|
@ -65,7 +60,6 @@ Oil_boi
|
||||||
pitchum
|
pitchum
|
||||||
PrairieAstronomer
|
PrairieAstronomer
|
||||||
PrairieWind
|
PrairieWind
|
||||||
River River
|
|
||||||
Rocher Laurent
|
Rocher Laurent
|
||||||
rootyjr
|
rootyjr
|
||||||
Rootyjr
|
Rootyjr
|
||||||
|
@ -74,7 +68,6 @@ Sab Pyrope
|
||||||
Saku Laesvuori
|
Saku Laesvuori
|
||||||
sfan5
|
sfan5
|
||||||
SmallJoker
|
SmallJoker
|
||||||
Sumyjkl
|
|
||||||
superfloh247
|
superfloh247
|
||||||
Sven792
|
Sven792
|
||||||
Sydney Gems
|
Sydney Gems
|
||||||
|
@ -82,7 +75,6 @@ talamh
|
||||||
TechDudie
|
TechDudie
|
||||||
Thinking
|
Thinking
|
||||||
Tianyang Zhang
|
Tianyang Zhang
|
||||||
unknown
|
|
||||||
U.N.Owen
|
U.N.Owen
|
||||||
Wouters Dorian
|
Wouters Dorian
|
||||||
wuniversales
|
wuniversales
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
Please run `./update_credits.sh` from [tools](../../../tools) folder to update contributor list.
|
Please run the following command to update contributor list:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# git log --pretty="%an" | sort | uniq >CONTRUBUTOR_LIST.txt
|
||||||
|
```
|
||||||
|
|
||||||
Please check that there is no error on execution, and `CONTRUBUTOR_LIST.txt` is updated.
|
Please check that there is no error on execution, and `CONTRUBUTOR_LIST.txt` is updated.
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,59 @@
|
||||||
# textdomain: mcl_death_messages
|
# textdomain: mcl_death_messages
|
||||||
@1 went up in flames=@1 a marché dans les flammes
|
@1 was fatally hit by an arrow.=@1 a été mortellement touché par une flèche.
|
||||||
@1 walked into fire whilst fighting @2=@1 a marché dans les flammes en combattant @2
|
@1 has been killed with an arrow.=@1 a été tué avec une flèche.
|
||||||
@1 was struck by lightning=@1 a été frappé par la foudre
|
@1 was shot by an arrow from @2.=@1 a été abattu par une flèche de @2.
|
||||||
@1 was struck by lightning whilst fighting @2=@1 a été frappé par la foudre en combattant @2
|
@1 was shot by an arrow from a skeleton.=@1 a été abattu par une flèche d'un squelette.
|
||||||
@1 burned to death=@1 a brûlé vif
|
@1 was shot by an arrow from a stray.=@1 a été abattu par une flèche d'un vagabond.
|
||||||
@1 was burnt to a crisp whilst fighting @2=@1 a brûlé comme une saucisse en combattant @2
|
@1 was shot by an arrow from an illusioner.=@1 a été abattu par une flèche d'un illusionniste.
|
||||||
@1 tried to swim in lava=@1 a tenté de nager dans la lave
|
@1 was shot by an arrow.=@1 a été abattu par une flèche.
|
||||||
@1 tried to swim in lava to escape @2=@1 a tenté de nager dans la lave pour échapper à @2
|
@1 forgot to breathe.=@1 a oublié de respirer.
|
||||||
@1 discovered the floor was lava=@1 a découvert que le sol était en lave
|
@1 drowned.=@1 s'est noyé.
|
||||||
@1 walked into danger zone due to @2=@1 a marché dans la zone de danger à cause de @2
|
@1 ran out of oxygen.=@1 a manqué d'oxygène.
|
||||||
@1 suffocated in a wall=@1 est mort asphyxié dans un mur
|
@1 was killed by @2.=@1 a été tué par @2.
|
||||||
@1 suffocated in a wall whilst fighting @2=@1 est mort asphyxié dans un mur en combattant @2
|
@1 was killed.=@1 a été tué.
|
||||||
@1 drowned=@1 s'est noyé
|
@1 was killed by a mob.=@1 a été tué par un mob.
|
||||||
@1 drowned whilst trying to escape @2=@1 s'est noyé en essayant d'échapper à @2
|
@1 was burned to death by a blaze's fireball.=@1 a été brûlé vif par la boule de feu d'un blaze.
|
||||||
@1 starved to death=@1 est mort de faim
|
@1 was killed by a fireball from a blaze.=@1 a été tué par une boule de feu lors d'un blaze.
|
||||||
@1 starved to death whilst fighting @2=@1 est mort de faim en combattant @2
|
@1 was burned by a fire charge.=@1 a été brûlé par un incendie.
|
||||||
@1 was pricked to death=@1 a été piqué à mort
|
A ghast scared @1 to death.=Un ghast a éffrayé @1 à mort.
|
||||||
@1 walked into a cactus whilst trying to escape @2=@1 a marché dans un cactus en essayant d'échapper à @2
|
@1 has been fireballed by a ghast.=@1 a été pétrifié par un ghast.
|
||||||
@1 hit the ground too hard=@1 a heurté le sol trop fort
|
@1 fell from a high cliff.=@1 est tombé d'une haute falaise.
|
||||||
@1 hit the ground too hard whilst trying to escape @2=@1 a heurté le sol trop fort en essayant d'échapper à @2
|
@1 took fatal fall damage.=@1 a succombé à un chute mortelle.
|
||||||
@1 experienced kinetic energy=@1 a expérimenté l'énergie cinétique
|
@1 fell victim to gravity.=@1 a été victime de la gravité.
|
||||||
@1 experienced kinetic energy whilst trying to escape @2=@1 a expérimenté l'énergie cinétique en essayant d'échapper à @2
|
@1 died.=@1 est mort.
|
||||||
@1 fell out of the world=@1 est tombé hors du monde
|
@1 was killed by a zombie.=@1 a été tué par un zombie.
|
||||||
@1 didn't want to live in the same world as @2=@1 ne voulait vivre dans le même monde que @2
|
@1 was killed by a baby zombie.=@1 a été tué par un bébé zombie.
|
||||||
@1 died=@1 est mort
|
@1 was killed by a blaze.=@1 a été tué par un blaze.
|
||||||
@1 died because of @2=@1 est mort à cause de @2
|
@1 was killed by a slime.=@1 a été tué par un slime.
|
||||||
@1 was killed by magic=@1 a été tué par magie
|
@1 was killed by a witch.=@1 a été tué par un sorcier.
|
||||||
@1 was killed by magic whilst trying to escape @2=@1 a été tué par magie en essayant d'échapper à @2
|
@1 was killed by a magma cube.=@1 a été tué par un cube de magma.
|
||||||
@1 was killed by @2 using magic=@1 a été tué par @2 en utilisant la magie
|
@1 was killed by a wolf.=@1 a été tué par un loup.
|
||||||
@1 was killed by @2 using @3=@1 a été tué par @2 en utilisant @3
|
@1 was killed by a cat.=@1 a été tué par un chat.
|
||||||
@1 was roasted in dragon breath=@1 a été rôti dans le souffle du dragon
|
@1 was killed by an ocelot.=@1 a été tué par un ocelot.
|
||||||
@1 was roasted in dragon breath by @2=@1 a été rôti dans le souffle du dragon par @2
|
@1 was killed by an ender dragon.=@1 a été tué par un ender dragon.
|
||||||
@1 withered away=@1 s'est flétri
|
@1 was killed by a wither.=@1 a été tué par un wither.
|
||||||
@1 withered away whilst fighting @2=@1 s'est flétri en combattant @2
|
@1 was killed by an enderman.=@1 a été tué par un enderman.
|
||||||
@1 was shot by a skull from @2=@1 a été abattu par un crane de @2
|
@1 was killed by an endermite.=@1 a été tué par un endermite.
|
||||||
@1 was squashed by a falling anvil=@1 a été écrasé par une enclume
|
@1 was killed by a ghast.=@1 a été tué par un ghast.
|
||||||
@1 was squashed by a falling anvil whilst fighting @2=@1 a été écrasé par une enclume en combattant @2
|
@1 was killed by an elder guardian.=@1 a été tué par un grand gardien.
|
||||||
@1 was squashed by a falling block=@1 a été écrasé par un bloc tombant
|
@1 was killed by a guardian.=@1 a été tué par un gardien.
|
||||||
@1 was squashed by a falling block whilst fighting @2=@1 a été écrasé par un bloc tombant en combattant @2
|
@1 was killed by an iron golem.=@1 a été tué par un golem de fer.
|
||||||
@1 was slain by @2=@1 a été tué par @2
|
@1 was killed by a polar_bear.=@1 a été tué par un ours blanc.
|
||||||
@1 was slain by @2 using @3=@1 a été tué par @2 avec @3
|
@1 was killed by a killer bunny.=@1 a été tué par un lapin tueur.
|
||||||
@1 was shot by @2=@1 a été abattu par @2
|
@1 was killed by a shulker.=@1 a été tué par un shulker.
|
||||||
@1 was shot by @2 using @3=@1 a été abattu par @2 avec @3
|
@1 was killed by a silverfish.=@1 a été tué par un poisson d'argent.
|
||||||
@1 was fireballed by @2=@1 a reçu une boule de feu de @2
|
@1 was killed by a skeleton.=@1 a été tué par un squelette.
|
||||||
@1 was fireballed by @2 using @3=@1 a reçu une boule de feu de @2 en utilisant @3
|
@1 was killed by a stray.=@1 a été tué par un vagabond.
|
||||||
@1 was killed trying to hurt @2=@1 a été tué en essayant de blesser @2
|
@1 was killed by a slime.=@1 a été tué par un slime.
|
||||||
@1 was killed by @3 trying to hurt @2=@1 a été tué par @3 en essayant de blesser @2
|
@1 was killed by a spider.=@1 a été tué par une araignée.
|
||||||
@1 blew up=@1 a explosé
|
@1 was killed by a cave spider.=@1 a été tué par une araignée venimeuse.
|
||||||
@1 was blown up by @2=@1 a été explosé par @2
|
@1 was killed by a vex.=@1 a été tué par un vex.
|
||||||
@1 was blown up by @2 using @3=@1 a été explosé par @2 en utilisant @3
|
@1 was killed by an evoker.=@1 a été tué par un invocateur.
|
||||||
@1 was squished too much=@1 a été trop écrabouillé
|
@1 was killed by an illusioner.=@1 a été tué par un illusionniste.
|
||||||
@1 was squashed by @2=@1 a été écrasé par @2
|
@1 was killed by a vindicator.=@1 a été tué par un vindicateur.
|
||||||
@1 went off with a bang=@1 est parti avec un bang
|
@1 was killed by a zombie villager.=@1 a été tué par un villageois zombie.
|
||||||
@1 went off with a bang due to a firework fired from @3 by @2=@1 est parti avec un bang à cause d'un feu d'artifice tiré de @3 par @2
|
@1 was killed by a husk.=@1 a été tué par un zombie momie.
|
||||||
|
@1 was killed by a baby husk.=@1 a été tué par un bébé zombie momie.
|
||||||
|
@1 was killed by a zombie pigman.=@1 a été tué par un zombie-couchon.
|
||||||
|
@1 was killed by a baby zombie pigman.=@1 a été tué par un bébé zombie-couchon
|
||||||
|
@1 was slain by @2.=@1 a été tué par @2
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
@1 was roasted in dragon breath by @2=
|
@1 was roasted in dragon breath by @2=
|
||||||
@1 withered away=
|
@1 withered away=
|
||||||
@1 withered away whilst fighting @2=
|
@1 withered away whilst fighting @2=
|
||||||
|
@1 was killed by magic=
|
||||||
@1 was shot by a skull from @2=
|
@1 was shot by a skull from @2=
|
||||||
@1 was squashed by a falling anvil=
|
@1 was squashed by a falling anvil=
|
||||||
@1 was squashed by a falling anvil whilst fighting @2=
|
@1 was squashed by a falling anvil whilst fighting @2=
|
||||||
|
@ -40,6 +41,8 @@
|
||||||
@1 was squashed by a falling block whilst fighting @2=
|
@1 was squashed by a falling block whilst fighting @2=
|
||||||
@1 was slain by @2=
|
@1 was slain by @2=
|
||||||
@1 was slain by @2 using @3=
|
@1 was slain by @2 using @3=
|
||||||
|
@1 was slain by @2=
|
||||||
|
@1 was slain by @2 using @3=
|
||||||
@1 was shot by @2=
|
@1 was shot by @2=
|
||||||
@1 was shot by @2 using @3=
|
@1 was shot by @2 using @3=
|
||||||
@1 was fireballed by @2=
|
@1 was fireballed by @2=
|
||||||
|
|
|
@ -1,28 +1,14 @@
|
||||||
local refresh_interval = .63
|
local refresh_interval = .63
|
||||||
local huds = {}
|
local huds = {}
|
||||||
local default_debug = 5
|
local default_debug = 3
|
||||||
local after = minetest.after
|
local after = minetest.after
|
||||||
local get_connected_players = minetest.get_connected_players
|
local get_connected_players = minetest.get_connected_players
|
||||||
local get_biome_name = minetest.get_biome_name
|
local get_biome_name = minetest.get_biome_name
|
||||||
local get_biome_data = minetest.get_biome_data
|
local get_biome_data = minetest.get_biome_data
|
||||||
local get_node = minetest.get_node
|
|
||||||
local format = string.format
|
local format = string.format
|
||||||
local table_concat = table.concat
|
|
||||||
local floor = math.floor
|
|
||||||
local minetest_get_gametime = minetest.get_gametime
|
|
||||||
local get_voxel_manip = minetest.get_voxel_manip
|
|
||||||
|
|
||||||
local min1, min2, min3
|
local min1, min2, min3 = mcl_mapgen.overworld.min, mcl_mapgen.end_.min, mcl_mapgen.nether.min
|
||||||
local max1, max2, max3
|
local max1, max2, max3 = mcl_mapgen.overworld.max, mcl_mapgen.end_.max, mcl_mapgen.nether.max + 128
|
||||||
local CS
|
|
||||||
|
|
||||||
local get_local_settings = function()
|
|
||||||
min1, min2, min3 = mcl_mapgen.overworld.min, mcl_mapgen.end_.min, mcl_mapgen.nether.min
|
|
||||||
max1, max2, max3 = mcl_mapgen.overworld.max, mcl_mapgen.end_.max, mcl_mapgen.nether.max+128
|
|
||||||
CS = mcl_mapgen.CS_NODES
|
|
||||||
end
|
|
||||||
get_local_settings()
|
|
||||||
mcl_mapgen.register_on_settings_changed(get_local_settings)
|
|
||||||
|
|
||||||
local modname = minetest.get_current_modname()
|
local modname = minetest.get_current_modname()
|
||||||
local modpath = minetest.get_modpath(modname)
|
local modpath = minetest.get_modpath(modname)
|
||||||
|
@ -31,7 +17,6 @@ local storage = minetest.get_mod_storage()
|
||||||
local player_dbg = minetest.deserialize(storage:get_string("player_dbg") or "return {}") or {}
|
local player_dbg = minetest.deserialize(storage:get_string("player_dbg") or "return {}") or {}
|
||||||
|
|
||||||
local function get_text(pos, bits)
|
local function get_text(pos, bits)
|
||||||
local pos = pos
|
|
||||||
local bits = bits
|
local bits = bits
|
||||||
if bits == 0 then return "" end
|
if bits == 0 then return "" end
|
||||||
local y = pos.y
|
local y = pos.y
|
||||||
|
@ -42,42 +27,16 @@ local function get_text(pos, bits)
|
||||||
elseif y >= min2 and y <= max2 then
|
elseif y >= min2 and y <= max2 then
|
||||||
y = y - min2
|
y = y - min2
|
||||||
end
|
end
|
||||||
|
local biome_data = get_biome_data(pos)
|
||||||
local will_show_mapgen_status = bits % 8 > 3
|
local biome_name = biome_data and get_biome_name(biome_data.biome) or "No biome"
|
||||||
local will_show_coordinates = bits % 4 > 1
|
local text
|
||||||
local will_show_biome_name = bits % 2 > 0
|
if bits == 1 then
|
||||||
local will_be_shown = {}
|
text = biome_name
|
||||||
|
elseif bits == 2 then
|
||||||
if will_show_biome_name then
|
text = format("x:%.1f y:%.1f z:%.1f", pos.x, y, pos.z)
|
||||||
local biome_data = get_biome_data(pos)
|
elseif bits == 3 then
|
||||||
local biome_name = biome_data and get_biome_name(biome_data.biome) or "No biome"
|
text = format("%s x:%.1f y:%.1f z:%.1f", biome_name, pos.x, y, pos.z)
|
||||||
will_be_shown[#will_be_shown + 1] = biome_name
|
|
||||||
end
|
end
|
||||||
if will_show_coordinates then
|
|
||||||
local coordinates = format("x:%.1f y:%.1f z:%.1f", pos.x, y, pos.z)
|
|
||||||
will_be_shown[#will_be_shown + 1] = coordinates
|
|
||||||
end
|
|
||||||
if will_show_mapgen_status then
|
|
||||||
local pos_x = floor(pos.x)
|
|
||||||
local pos_y = floor(pos.y)
|
|
||||||
local pos_z = floor(pos.z)
|
|
||||||
local c = 0
|
|
||||||
for x = pos_x - CS, pos_x + CS, CS do
|
|
||||||
for y = pos_y - CS, pos_y + CS, CS do
|
|
||||||
for z = pos_z - CS, pos_z + CS, CS do
|
|
||||||
local pos = {x = x, y = y, z = z}
|
|
||||||
get_voxel_manip():read_from_map(pos, pos)
|
|
||||||
local node = get_node(pos)
|
|
||||||
if node.name ~= "ignore" then c = c + 1 end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local p = floor(c / 27 * 100 + 0.5)
|
|
||||||
local status = format("Generated %u%% (%u/27 chunks)", p, c)
|
|
||||||
will_be_shown[#will_be_shown + 1] = status
|
|
||||||
end
|
|
||||||
|
|
||||||
local text = table_concat(will_be_shown, ' ')
|
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -123,11 +82,11 @@ minetest.register_on_authplayer(function(name, ip, is_success)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_chatcommand("debug",{
|
minetest.register_chatcommand("debug",{
|
||||||
description = S("Set debug bit mask: 0 = disable, 1 = biome name, 2 = coordinates, 4 = mapgen status, 7 = all"),
|
description = S("Set debug bit mask: 0 = disable, 1 = biome name, 2 = coordinates, 3 = all"),
|
||||||
func = function(name, params)
|
func = function(name, params)
|
||||||
local dbg = math.floor(tonumber(params) or default_debug)
|
local dbg = math.floor(tonumber(params) or default_debug)
|
||||||
if dbg < 0 or dbg > 7 then
|
if dbg < 0 or dbg > 3 then
|
||||||
minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 7))
|
minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 3))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if dbg == default_debug then
|
if dbg == default_debug then
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# textdomain: mcl_info
|
# textdomain: mcl_info
|
||||||
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 4 @= mapgen status, 7 @= all=Réglage du masque de débugage : 0 @= désactiver, 1 @= nom de biome, 2 @= coordonnées, 4 @= mapgen status, 7 @= tout=
|
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Réglage du masque de débugage : 0 @= désactiver, 1 @= nom de biome, 2 @= coordonnées, 3 @= tout=
|
||||||
Error! Possible values are integer numbers from @1 to @2=Erreur ! Les valeurs autorisées sont des nombres entiers de @1 à @2
|
Error! Possible values are integer numbers from @1 to @2=Erreur ! Les valeurs autorisées sont des nombres entiers de @1 à @2
|
||||||
Debug bit mask set to @1=Masque de débugage réglé à @1
|
Debug bit mask set to @1=Masque de débugage réglé à @1
|
|
@ -1,4 +1,4 @@
|
||||||
# textdomain: mcl_info
|
# textdomain: mcl_info
|
||||||
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 4 @= mapgen status, 7 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 4 @= состояние мапгена, 7 @= всё
|
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 3 @= всё
|
||||||
Error! Possible values are integer numbers from @1 to @2=Ошибка! Допустимые значения - целые числа от @1 до @2
|
Error! Possible values are integer numbers from @1 to @2=Ошибка! Допустимые значения - целые числа от @1 до @2
|
||||||
Debug bit mask set to @1=Отладочной битовой маске присвоено значение @1
|
Debug bit mask set to @1=Отладочной битовой маске присвоено значение @1
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# textdomain: mcl_info
|
# textdomain: mcl_info
|
||||||
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 4 @= mapgen status, 7 @= all=
|
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=
|
||||||
Error! Possible values are integer numbers from @1 to @2=
|
Error! Possible values are integer numbers from @1 to @2=
|
||||||
Debug bit mask set to @1=
|
Debug bit mask set to @1=
|
||||||
|
|
|
@ -34,7 +34,7 @@ minetest.register_on_mods_loaded(function()
|
||||||
for name,def in pairs(minetest.registered_items) do
|
for name,def in pairs(minetest.registered_items) do
|
||||||
if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then
|
if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then
|
||||||
local function is_redstone(def)
|
local function is_redstone(def)
|
||||||
return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effector_off
|
return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off
|
||||||
end
|
end
|
||||||
local function is_tool(def)
|
local function is_tool(def)
|
||||||
return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil)
|
return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil)
|
||||||
|
@ -339,6 +339,14 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
|
||||||
if name == "inv" then
|
if name == "inv" then
|
||||||
inv_bg = "crafting_inventory_creative_survival.png"
|
inv_bg = "crafting_inventory_creative_survival.png"
|
||||||
|
|
||||||
|
-- Show armor and player image
|
||||||
|
local player_preview
|
||||||
|
if minetest.settings:get_bool("3d_player_preview", true) then
|
||||||
|
player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "")
|
||||||
|
else
|
||||||
|
player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]"
|
||||||
|
end
|
||||||
|
|
||||||
-- Background images for armor slots (hide if occupied)
|
-- Background images for armor slots (hide if occupied)
|
||||||
local armor_slot_imgs = ""
|
local armor_slot_imgs = ""
|
||||||
local inv = player:get_inventory()
|
local inv = player:get_inventory()
|
||||||
|
@ -378,7 +386,8 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
|
||||||
|
|
||||||
armor_slot_imgs..
|
armor_slot_imgs..
|
||||||
-- player preview
|
-- player preview
|
||||||
mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "")..
|
player_preview..
|
||||||
|
|
||||||
-- crafting guide button
|
-- crafting guide button
|
||||||
"image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]"..
|
"image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]"..
|
||||||
"tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]"..
|
"tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]"..
|
||||||
|
|
|
@ -61,6 +61,14 @@ local function set_inventory(player, armor_change_only)
|
||||||
inv:set_width("craft", 2)
|
inv:set_width("craft", 2)
|
||||||
inv:set_size("craft", 4)
|
inv:set_size("craft", 4)
|
||||||
|
|
||||||
|
-- Show armor and player image
|
||||||
|
local player_preview
|
||||||
|
if minetest.settings:get_bool("3d_player_preview", true) then
|
||||||
|
player_preview = mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "")
|
||||||
|
else
|
||||||
|
player_preview = "image[1.1,0.2;2,4;"..mcl_player.player_get_preview(player).."]"
|
||||||
|
end
|
||||||
|
|
||||||
local armor_slots = {"helmet", "chestplate", "leggings", "boots"}
|
local armor_slots = {"helmet", "chestplate", "leggings", "boots"}
|
||||||
local armor_slot_imgs = ""
|
local armor_slot_imgs = ""
|
||||||
for a=1,4 do
|
for a=1,4 do
|
||||||
|
@ -75,7 +83,7 @@ local function set_inventory(player, armor_change_only)
|
||||||
|
|
||||||
local form = "size[9,8.75]"..
|
local form = "size[9,8.75]"..
|
||||||
"background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]"..
|
"background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]"..
|
||||||
mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "")..
|
player_preview..
|
||||||
--armor
|
--armor
|
||||||
"list[current_player;armor;0,0;1,1;1]"..
|
"list[current_player;armor;0,0;1,1;1]"..
|
||||||
"list[current_player;armor;0,1;1,1;2]"..
|
"list[current_player;armor;0,1;1,1;2]"..
|
||||||
|
|
|
@ -3,7 +3,6 @@ Recipe book=Livre de recettes
|
||||||
Help=Aide
|
Help=Aide
|
||||||
Select player skin=Sélectionnez l'apparence du joueur
|
Select player skin=Sélectionnez l'apparence du joueur
|
||||||
Achievements=Accomplissements
|
Achievements=Accomplissements
|
||||||
Switch stack size=Échanger les tailles de piles
|
|
||||||
Building Blocks=Blocs de Construction
|
Building Blocks=Blocs de Construction
|
||||||
Decoration Blocks=Blocs de Décoration
|
Decoration Blocks=Blocs de Décoration
|
||||||
Redstone=Redstone
|
Redstone=Redstone
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
# textdomain: mcl_bells
|
# textdomain: mcl_observers
|
||||||
Bell=Cloche
|
Bell=Cloche
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
# textdomain: mcl_bells
|
# textdomain: mcl_observers
|
||||||
Bell=
|
Bell=
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
# textdomain: mcl_amethyst
|
|
||||||
Amethyst Cluster= Abarolada d'Ametista
|
|
||||||
Amethyst Cluster is the final growth of amethyst bud.= L'Abarolada d'Ametista es l'etapa fin finala de creissança dau borron d'ametista.
|
|
||||||
Amethyst Shard= Esclap d'Ametista
|
|
||||||
An amethyst shard is a crystalline mineral.= Un Esclap d'Ametista es un minerau cristallin.
|
|
||||||
Block of Amethyst= Blòc d'Ametista
|
|
||||||
Budding Amethyst= Ametista Borronanta
|
|
||||||
Calcite= Calcita
|
|
||||||
Calcite can be found as part of amethyst geodes.= La Calcita pòt se trobar dins una geòda d'ametista.
|
|
||||||
Large Amethyst Bud= Borron d'Ametista Bèl
|
|
||||||
Large Amethyst Bud is the third growth of amethyst bud.= Lo Borron d'Ametista Bèl es la tresèima etapa de creissança dau borron d'ametista.
|
|
||||||
Medium Amethyst Bud= Borron d'Ametista Mejan
|
|
||||||
Medium Amethyst Bud is the second growth of amethyst bud.= Lo Borron d'Ametista Mejan es la segonda etapa de creissança dau borron d'ametista.
|
|
||||||
Small Amethyst Bud= Borron d'Ametista Pichòt
|
|
||||||
Small Amethyst Bud is the first growth of amethyst bud.= Lo Borron d'Ametista Pichòt es la pormèira etapa de creissança dau borron d'ametista.
|
|
||||||
The Block of Amethyst is a decoration block crafted from amethyst shards.= Lo Blòc d'Ametista es un blòc de decoracion fabricat dempuèi d'esclaps d'ametista.
|
|
||||||
The Budding Amethyst can grow amethyst= L'Ametista Borronanta pòt créisser l'ametista.
|
|
||||||
Tinted Glass= Veire Tintat
|
|
||||||
Tinted Glass is a type of glass which blocks lights while it is visually transparent.= Lo Veire Tintat es un tipe de veire que barra la lutz en estant clarent.
|
|
|
@ -1,288 +0,0 @@
|
||||||
# mcl_armor
|
|
||||||
|
|
||||||
This mod implements the ability of registering armors.
|
|
||||||
|
|
||||||
## Registering an Armor Set
|
|
||||||
|
|
||||||
The `mcl_armor.register_set()` function aims to simplify the process of registering a full set of armor.
|
|
||||||
|
|
||||||
This function register four pieces of armor (head, torso, leggings, feets) based on a definition table:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
mcl_armor.register_set({
|
|
||||||
--name of the armor material (used for generating itemstrings)
|
|
||||||
name = "dummy_armor",
|
|
||||||
|
|
||||||
--description of the armor material
|
|
||||||
--do NOT translate this string, it will be concatenated will each piece of armor's description and result will be automatically fetched from your mod's translation files
|
|
||||||
description = "Dummy Armor",
|
|
||||||
|
|
||||||
--overide description of each armor piece
|
|
||||||
--do NOT localize this string
|
|
||||||
descriptions = {
|
|
||||||
head = "Cap", --default: "Helmet"
|
|
||||||
torso = "Tunic", --default: "Chestplate"
|
|
||||||
legs = "Pants", --default: "Leggings"
|
|
||||||
feet = "Shoes", --default: "Boots"
|
|
||||||
},
|
|
||||||
|
|
||||||
--this is used to calculate each armor piece durability with the minecraft algorithm
|
|
||||||
--head durability = durability * 0.6857 + 1
|
|
||||||
--torso durability = durability * 1.0 + 1
|
|
||||||
--legs durability = durability * 0.9375 + 1
|
|
||||||
--feet durability = durability * 0.8125 + 1
|
|
||||||
durability = 80,
|
|
||||||
|
|
||||||
--this is used then you need to specify the durability of each piece of armor
|
|
||||||
--this field have the priority over the durability one
|
|
||||||
--if the durability of some pieces of armor isn't specified in this field, the durability field will be used insteed
|
|
||||||
durabilities = {
|
|
||||||
head = 200,
|
|
||||||
torso = 500,
|
|
||||||
legs = 400,
|
|
||||||
feet = 300,
|
|
||||||
},
|
|
||||||
|
|
||||||
--this define how good enchants you will get then enchanting one piece of the armor in an enchanting table
|
|
||||||
--if set to zero or nil, the armor will not be enchantable
|
|
||||||
enchantability = 15,
|
|
||||||
|
|
||||||
--this define how much each piece of armor protect the player
|
|
||||||
--these points will be shown in the HUD (chestplate bar above the health bar)
|
|
||||||
points = {
|
|
||||||
head = 1,
|
|
||||||
torso = 3,
|
|
||||||
legs = 2,
|
|
||||||
feet = 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
--this attribute reduce strong damage even more
|
|
||||||
--See https://minecraft.fandom.com/wiki/Armor#Armor_toughness for more explanations
|
|
||||||
--default: 0
|
|
||||||
toughness = 2,
|
|
||||||
|
|
||||||
--this field is used to specify some items groups that will be added to each piece of armor
|
|
||||||
--please note that some groups do NOT need to be added by hand, because they are already handeled by the register function:
|
|
||||||
--(armor, combat_armor, armor_<element>, combat_armor_<element>, mcl_armor_points, mcl_armor_toughness, mcl_armor_uses, enchantability)
|
|
||||||
groups = {op_armor = 1},
|
|
||||||
|
|
||||||
--specify textures that will be overlayed on the entity wearing the armor
|
|
||||||
--these fields have default values and its recommanded to keep the code clean by just using the default name for your textures
|
|
||||||
textures = {
|
|
||||||
head = "dummy_texture.png", --default: "<modname>_helmet_<material>.png"
|
|
||||||
torso = "dummy_texture.png", --default: "<modname>_chestplate_<material>.png"
|
|
||||||
legs = "dummy_texture.png", --default: "<modname>_leggings_<material>.png"
|
|
||||||
feet = "dummy_texture.png", --default: "<modname>_boots_<material>.png"
|
|
||||||
},
|
|
||||||
--you can also define these fields as functions, that will be called each time the API function mcl_armor.update(obj) is called (every time you equip/unequip some armor piece, take damage, and more)
|
|
||||||
--note that the enchanting overlay will not appear unless you implement it in the function
|
|
||||||
--this allow to make armors where the textures change whitout needing to register many other armors with different textures
|
|
||||||
textures = {
|
|
||||||
head = function(obj, itemstack)
|
|
||||||
if mcl_enchanting.is_enchanted(itemstack) then
|
|
||||||
return "dummy_texture.png^"..mcl_enchanting.overlay
|
|
||||||
else
|
|
||||||
return "dummy_texture.png"
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
|
|
||||||
--inventory textures aren't definable using a table similar to textures or previews
|
|
||||||
--you are forced to use the default texture names which are:
|
|
||||||
--head: "<modname>_inv_helmet_<material>.png
|
|
||||||
--torso: "<modname>_inv_chestplate_<material>.png
|
|
||||||
--legs: "<modname>_inv_leggings_<material>.png
|
|
||||||
--feet: "<modname>_inv_boots_<material>.png
|
|
||||||
|
|
||||||
--this callback table allow you to define functions that will be called each time an entity equip an armor piece or the mcl_armor.on_equip() function is called
|
|
||||||
--the functions accept two arguments: obj and itemstack
|
|
||||||
on_equip_callbacks = {
|
|
||||||
head = function(obj, itemstack)
|
|
||||||
--do stuff
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
|
|
||||||
--this callback table allow you to define functions that will be called each time an entity unequip an armor piece or the mcl_armor.on_unequip() function is called
|
|
||||||
--the functions accept two arguments: obj and itemstack
|
|
||||||
on_unequip_callbacks = {
|
|
||||||
head = function(obj, itemstack)
|
|
||||||
--do stuff
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
|
|
||||||
--this callback table allow you to define functions that will be called then an armor piece break
|
|
||||||
--the functions accept one arguments: obj
|
|
||||||
--the itemstack isn't sended due to how minetest handle items which have a zero durability
|
|
||||||
on_break_callbacks = {
|
|
||||||
head = function(obj)
|
|
||||||
--do stuff
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
|
|
||||||
--this is used to generate automaticaly armor crafts based on each element type folowing the regular minecraft pattern
|
|
||||||
--if set to nil no craft will be added
|
|
||||||
craft_material = "mcl_mobitems:leather",
|
|
||||||
|
|
||||||
--this is used to generate cooking crafts for each piece of armor
|
|
||||||
--if set to nil no craft will be added
|
|
||||||
cook_material = "mcl_core:gold_nugget", --cooking any piece of this armor will output a gold nugged
|
|
||||||
|
|
||||||
--this is used for allowing each piece of the armor to be repaired by using an anvil with repair_material as aditionnal material
|
|
||||||
--it basicaly set the _repair_material item field of each piece of the armor
|
|
||||||
--if set to nil no repair material will be added
|
|
||||||
repair_material = "mcl_core:iron_ingot",
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## Creating an Armor Piece
|
|
||||||
|
|
||||||
If you don't want to register a full set of armor, then you will need to manually register your own single item.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
minetest.register_tool("dummy_mod:random_armor", {
|
|
||||||
description = S("Random Armor"),
|
|
||||||
|
|
||||||
--these two item fields are used for ingame documentation
|
|
||||||
--the mcl_armor.longdesc and mcl_armor.usage vars contains the basic usage and purpose of a piece of armor
|
|
||||||
--these vars may not be enough for that you want to do, so you may add some extra informations like that:
|
|
||||||
--_doc_items_longdesc = mcl_armor.longdesc.." "..S("Some extra informations.")
|
|
||||||
_doc_items_longdesc = mcl_armor.longdesc,
|
|
||||||
_doc_items_usagehelp = mcl_armor.usage,
|
|
||||||
|
|
||||||
--this field is similar to any item definition in minetest
|
|
||||||
--it just set the image shown then the armor is dropped as an item or inside an inventory
|
|
||||||
inventory_image = "mcl_armor_inv_elytra.png",
|
|
||||||
|
|
||||||
--this field is used by minetest internally and also by some helper functions
|
|
||||||
--in order for the tool to be shown is the right creative inventory tab, the right groups should be added
|
|
||||||
--"mcl_armor_uses" is required to give your armor a durability
|
|
||||||
--in that case, the armor can be worn by 10 points before breaking
|
|
||||||
--if you want the armor to be enchantable, you should also add the "enchantability" group, with the highest number the better enchants you can apply
|
|
||||||
groups = {armor = 1, non_combat_armor = 1, armor_torso = 1, non_combat_torso = 1, mcl_armor_uses = 10},
|
|
||||||
|
|
||||||
--this table is used by minetest for seraching item specific sounds
|
|
||||||
--the _mcl_armor_equip and _mcl_armor_unequip are used by the armor implementation to play sounds on equip and unequip
|
|
||||||
--note that you don't need to provide any file extention
|
|
||||||
sounds = {
|
|
||||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
|
||||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
|
||||||
},
|
|
||||||
|
|
||||||
--these fields should be initialised like that in most cases
|
|
||||||
--mcl_armor.equip_on_use is a function that try to equip the piece of armor you have in hand inside the right armor slot if the slot is empty
|
|
||||||
on_place = mcl_armor.equip_on_use,
|
|
||||||
on_secondary_use = mcl_armor.equip_on_use,
|
|
||||||
|
|
||||||
--this field define that the tool is ACTUALLY an armor piece and in which armor slot you can put it
|
|
||||||
--it should be set to "head", "torso", "legs" or "feet"
|
|
||||||
_mcl_armor_element = "torso",
|
|
||||||
|
|
||||||
|
|
||||||
--this field is used to provide the texture that will be overlayed on the object (player or mob) skin
|
|
||||||
--this field can be a texture name or a function that will be called each time the mcl_armor.update(obj) function is called
|
|
||||||
--see the mcl_armor.register_set() documentation for more explanations
|
|
||||||
_mcl_armor_texture = "mcl_armor_elytra.png"
|
|
||||||
|
|
||||||
--callbacks
|
|
||||||
--see the mcl_armor.register_set() documentation for more explanations
|
|
||||||
|
|
||||||
_on_equip = function(obj, itemstack)
|
|
||||||
end,
|
|
||||||
_on_unequip = function(obj, itemstack)
|
|
||||||
end,
|
|
||||||
_on_break = function(obj)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## Interacting with Armor of an Entity
|
|
||||||
|
|
||||||
Mods may want to interact with armor of an entity.
|
|
||||||
|
|
||||||
Most global functions not described here may not be stable or may be for internal use only.
|
|
||||||
|
|
||||||
You can equip a piece of armor on an entity inside a mod by using `mcl_armor.equip()`.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
--itemstack: an itemstack containing the armor piece to equip
|
|
||||||
--obj: the entity you want to equip the armor on
|
|
||||||
--swap: boolean, force equiping the armor piece, even if the entity already have one of the same type
|
|
||||||
mcl_armor.equip(itemstack, obj, swap)
|
|
||||||
```
|
|
||||||
|
|
||||||
You can update the entity apparence by using `mcl_armor.update()`.
|
|
||||||
|
|
||||||
This function put the armor overlay on the object's base texture.
|
|
||||||
If the object is player it will update his displayed armor points count in HUD.
|
|
||||||
|
|
||||||
This function will work both on players and mobs.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
--obj: the entity you want the apparence to be updated
|
|
||||||
mcl_armor.update(obj)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Handling Enchantments
|
|
||||||
|
|
||||||
Armors can be enchanted in most cases.
|
|
||||||
|
|
||||||
The enchanting part of MineClone2 is separated from the armor part, but closely linked.
|
|
||||||
|
|
||||||
Existing armor enchantments in Minecraft improve most of the time how the armor protect the entity from damage.
|
|
||||||
|
|
||||||
The `mcl_armor.register_protection_enchantment()` function aims to simplificate the creation of such enchants.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
mcl_armor.register_protection_enchantment({
|
|
||||||
--this field is the id that will be used for registering enchanted book and store the enchant inside armor metadata.
|
|
||||||
--(his internal name)
|
|
||||||
id = "magic_protection",
|
|
||||||
|
|
||||||
--visible name of the enchant
|
|
||||||
--this field is used as the name of registered enchanted book and inside armor tooltip
|
|
||||||
--translation should be added
|
|
||||||
name = S("Magic Protection"),
|
|
||||||
|
|
||||||
--this field is used to know that the enchant currently do
|
|
||||||
--translation should be added
|
|
||||||
description = S("Reduces magic damage."),
|
|
||||||
|
|
||||||
--how many levels can the enchant have
|
|
||||||
--ex: 4 => I, II, III, IV
|
|
||||||
--default: 4
|
|
||||||
max_level = 4,
|
|
||||||
|
|
||||||
--which enchants this enchant will not be compatible with
|
|
||||||
--each of these values is a enchant id
|
|
||||||
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
|
|
||||||
|
|
||||||
--how much will the enchant consume from the enchantability group of the armor item
|
|
||||||
--default: 5
|
|
||||||
weight = 5,
|
|
||||||
|
|
||||||
--false => the enchant can be obtained in an enchanting table
|
|
||||||
--true => the enchant isn't obtainable in the enchanting table
|
|
||||||
--is true, you will probably need to implement some ways to obtain it
|
|
||||||
--even it the field is named "treasure", it will be no way to find it
|
|
||||||
--default: false
|
|
||||||
treasure = false,
|
|
||||||
|
|
||||||
--how much will damage be reduced
|
|
||||||
--see Minecraft Wiki for more informations
|
|
||||||
--https://minecraft.gamepedia.com/Armor#Damage_protection
|
|
||||||
--https://minecraft.gamepedia.com/Armor#Enchantments
|
|
||||||
factor = 1,
|
|
||||||
|
|
||||||
--restrict damage to one type
|
|
||||||
--allow the enchant to only protect of one type of damage
|
|
||||||
damage_type = "magic",
|
|
||||||
|
|
||||||
--restrict damage to one category
|
|
||||||
--allow to protect from many type of damage at once
|
|
||||||
--this is much less specific than damage_type and also much more customisable
|
|
||||||
--the "is_magic" flag is used in the "magic", "dragon_breath", "wither_skull" and "thorns" damage types
|
|
||||||
--you can checkout the mcl_damage source code for a list of availlable damage types and associated flags
|
|
||||||
--but be warned that mods can register additionnal damage types
|
|
||||||
damage_flag = "is_magic",
|
|
||||||
})
|
|
||||||
```
|
|
|
@ -94,6 +94,7 @@ function mcl_armor.register_set(def)
|
||||||
local on_unequip_callbacks = def.on_unequip_callbacks or {}
|
local on_unequip_callbacks = def.on_unequip_callbacks or {}
|
||||||
local on_break_callbacks = def.on_break_callbacks or {}
|
local on_break_callbacks = def.on_break_callbacks or {}
|
||||||
local textures = def.textures or {}
|
local textures = def.textures or {}
|
||||||
|
local previews = def.previews or {}
|
||||||
local durabilities = def.durabilities or {}
|
local durabilities = def.durabilities or {}
|
||||||
local element_groups = def.element_groups or {}
|
local element_groups = def.element_groups or {}
|
||||||
|
|
||||||
|
@ -133,7 +134,8 @@ function mcl_armor.register_set(def)
|
||||||
_on_break = on_break_callbacks[name] or def.on_break,
|
_on_break = on_break_callbacks[name] or def.on_break,
|
||||||
_mcl_armor_element = name,
|
_mcl_armor_element = name,
|
||||||
_mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png",
|
_mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png",
|
||||||
_mcl_upgradable = def.upgradable
|
_mcl_armor_preview = previews[name] or modname .. "_" .. itemname .. "_preview.png",
|
||||||
|
_mcl_upgradable = def.upgradable,
|
||||||
})
|
})
|
||||||
|
|
||||||
if def.craft_material then
|
if def.craft_material then
|
||||||
|
@ -220,6 +222,17 @@ function mcl_armor.update(obj)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local preview = def._mcl_armor_preview
|
||||||
|
|
||||||
|
if obj:is_player() and preview then
|
||||||
|
if type(preview) == "function" then
|
||||||
|
preview = preview(obj, itemstack)
|
||||||
|
end
|
||||||
|
if preview then
|
||||||
|
info.preview = "(player.png^[opacity:0^" .. def._mcl_armor_preview .. ")" .. (info.preview and "^" .. info.preview or "" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points")
|
info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points")
|
||||||
|
|
||||||
local mob_range_mob = def._mcl_armor_mob_range_mob
|
local mob_range_mob = def._mcl_armor_mob_range_mob
|
||||||
|
@ -242,6 +255,8 @@ function mcl_armor.update(obj)
|
||||||
info.texture = info.texture or "blank.png"
|
info.texture = info.texture or "blank.png"
|
||||||
|
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
|
info.preview = info.preview or "blank.png"
|
||||||
|
|
||||||
mcl_armor.update_player(obj, info)
|
mcl_armor.update_player(obj, info)
|
||||||
else
|
else
|
||||||
local luaentity = obj:get_luaentity()
|
local luaentity = obj:get_luaentity()
|
||||||
|
|
|
@ -6,44 +6,18 @@ Iron Helmet=Casque de Fer
|
||||||
Golden Helmet=Casque d'Or
|
Golden Helmet=Casque d'Or
|
||||||
Diamond Helmet=Casque de Diamant
|
Diamond Helmet=Casque de Diamant
|
||||||
Chain Helmet=Casque de Mailles
|
Chain Helmet=Casque de Mailles
|
||||||
Netherite Helmet=Casque de Netherite
|
|
||||||
Leather Tunic=Tunique en Cuir
|
Leather Tunic=Tunique en Cuir
|
||||||
Iron Chestplate=Plastron de Fer
|
Iron Chestplate=Plastron de Fer
|
||||||
Golden Chestplate=Plastron d'Or
|
Golden Chestplate=Plastron d'Or
|
||||||
Diamond Chestplate=Plastron de Diamant
|
Diamond Chestplate=Plastron de Diamant
|
||||||
Chain Chestplate=Cotte de Mailles
|
Chain Chestplate=Cotte de Mailles
|
||||||
Netherite Chestplate=Plastron de Netherite
|
|
||||||
Leather Pants=Pantalon de Cuir
|
Leather Pants=Pantalon de Cuir
|
||||||
Iron Leggings=Jambières de Fer
|
Iron Leggings=Jambières de Fer
|
||||||
Golden Leggings=Jambières d'Or
|
Golden Leggings=Jambières d'Or
|
||||||
Diamond Leggings=Jambières de Diamant
|
Diamond Leggings=Jambières de Diamant
|
||||||
Chain Leggings=Jambières de Mailles
|
Chain Leggings=Jambières de Mailles
|
||||||
Netherite Leggings=Jambières de Netherite
|
|
||||||
Leather Boots=Bottes de Cuir
|
Leather Boots=Bottes de Cuir
|
||||||
Iron Boots=Bottes de Fer
|
Iron Boots=Bottes de Fer
|
||||||
Golden Boots=Bottes d'Or
|
Golden Boots=Bottes d'Or
|
||||||
Diamond Boots=Bottes de Diamant
|
Diamond Boots=Bottes de Diamant
|
||||||
Chain Boots=Bottes de Mailles
|
Chain Boots=Bottes de Mailles
|
||||||
Netherite Boots=Bottes de Netherite
|
|
||||||
Elytra=Élytres
|
|
||||||
|
|
||||||
#Translations of enchantements
|
|
||||||
Increases underwater mining speed.=Augmente la vitesse de minage sous-marine.
|
|
||||||
Blast Protection=Protection contre les explosions
|
|
||||||
Reduces explosion damage and knockback.=Réduit les dégâts d'explosion et de recul.
|
|
||||||
Curse of Binding=Malédiction du lien éternel
|
|
||||||
Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=L'objet ne peut pas être retiré des emplacements d'armure sauf en cas de mort, de rupture ou en mode créatif.
|
|
||||||
Feather Falling=Chute amortie
|
|
||||||
Reduces fall damage.=Réduit les dégats de chute.
|
|
||||||
Fire Protection=Protection contre le feu
|
|
||||||
Reduces fire damage.=Reduit les dégats de feu.
|
|
||||||
Shooting consumes no regular arrows.=Le tir ne consomme pas de flèches standard.
|
|
||||||
Shoot 3 arrows at the cost of one.=Tirez sur 3 flèches au prix d'une.
|
|
||||||
Projectile Protection=Protection contre les projectiles
|
|
||||||
Reduces projectile damage.=Réduit les dommages causés par les projectiles.
|
|
||||||
Protection=Protection
|
|
||||||
Reduces most types of damage by 4% for each level.=Réduit la plupart des types de dégâts de 4% pour chaque niveau.
|
|
||||||
Thorns=Épines
|
|
||||||
Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflète une partie des dégâts subis lors de la frappe, au prix d'une réduction de la durabilité à chaque déclenchement.
|
|
||||||
Aqua Affinity=Affinité aquatique
|
|
||||||
|
|
||||||
|
|
|
@ -6,43 +6,19 @@ Iron Helmet=
|
||||||
Golden Helmet=
|
Golden Helmet=
|
||||||
Diamond Helmet=
|
Diamond Helmet=
|
||||||
Chain Helmet=
|
Chain Helmet=
|
||||||
Netherite Helmet=
|
|
||||||
Leather Tunic=
|
Leather Tunic=
|
||||||
Iron Chestplate=
|
Iron Chestplate=
|
||||||
Golden Chestplate=
|
Golden Chestplate=
|
||||||
Diamond Chestplate=
|
Diamond Chestplate=
|
||||||
Chain Chestplate=
|
Chain Chestplate=
|
||||||
Netherite Chestplate=
|
|
||||||
Leather Pants=
|
Leather Pants=
|
||||||
Iron Leggings=
|
Iron Leggings=
|
||||||
Golden Leggings=
|
Golden Leggings=
|
||||||
Diamond Leggings=
|
Diamond Leggings=
|
||||||
Chain Leggings=
|
Chain Leggings=
|
||||||
Netherite Leggings=
|
|
||||||
Leather Boots=
|
Leather Boots=
|
||||||
Iron Boots=
|
Iron Boots=
|
||||||
Golden Boots=
|
Golden Boots=
|
||||||
Diamond Boots=
|
Diamond Boots=
|
||||||
Chain Boots=
|
Chain Boots=
|
||||||
Netherite Boots=
|
|
||||||
Elytra=
|
Elytra=
|
||||||
|
|
||||||
#Translations of enchantements
|
|
||||||
Increases underwater mining speed.=
|
|
||||||
Blast Protection=
|
|
||||||
Reduces explosion damage and knockback.=
|
|
||||||
Curse of Binding=Malédiction du lien éternel
|
|
||||||
Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=
|
|
||||||
Feather Falling=
|
|
||||||
Reduces fall damage.=
|
|
||||||
Fire Protection=
|
|
||||||
Reduces fire damage.=
|
|
||||||
Shooting consumes no regular arrows.=
|
|
||||||
Shoot 3 arrows at the cost of one.=
|
|
||||||
Projectile Protection=
|
|
||||||
Reduces projectile damage.=
|
|
||||||
Protection=
|
|
||||||
Reduces most types of damage by 4% for each level.=
|
|
||||||
Thorns=
|
|
||||||
Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=
|
|
||||||
Aqua Affinity=
|
|
|
@ -63,7 +63,7 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", {
|
||||||
})
|
})
|
||||||
|
|
||||||
function mcl_armor.update_player(player, info)
|
function mcl_armor.update_player(player, info)
|
||||||
mcl_player.player_set_armor(player, info.texture)
|
mcl_player.player_set_armor(player, info.texture, info.preview)
|
||||||
|
|
||||||
local meta = player:get_meta()
|
local meta = player:get_meta()
|
||||||
meta:set_int("mcl_armor:armor_points", info.points)
|
meta:set_int("mcl_armor:armor_points", info.points)
|
||||||
|
|
After Width: | Height: | Size: 156 B |
After Width: | Height: | Size: 157 B |
After Width: | Height: | Size: 150 B |
After Width: | Height: | Size: 140 B |
After Width: | Height: | Size: 131 B |
After Width: | Height: | Size: 255 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 215 B |
After Width: | Height: | Size: 150 B |
After Width: | Height: | Size: 149 B |
After Width: | Height: | Size: 208 B |
After Width: | Height: | Size: 190 B |
After Width: | Height: | Size: 162 B |
After Width: | Height: | Size: 147 B |
After Width: | Height: | Size: 133 B |
After Width: | Height: | Size: 197 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 165 B |
|
@ -75,4 +75,3 @@ You can copy the pattern of a banner by placing two banners of the same color in
|
||||||
And one additional layer=Et une couche supplémentaire
|
And one additional layer=Et une couche supplémentaire
|
||||||
And @1 additional layers=Et @1 couches supplémentaires
|
And @1 additional layers=Et @1 couches supplémentaires
|
||||||
Paintable decoration=Décoration à peindre
|
Paintable decoration=Décoration à peindre
|
||||||
Preview Banner= Aperçu de la Bannière
|
|
|
@ -1,402 +0,0 @@
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
|
||||||
--[[
|
|
||||||
there are strings in meta, which are being used to see which effect will be given to the player(s)
|
|
||||||
Valid strings:
|
|
||||||
swiftness
|
|
||||||
leaping
|
|
||||||
strenght
|
|
||||||
regeneration
|
|
||||||
]]--
|
|
||||||
|
|
||||||
mcl_beacons = {
|
|
||||||
blocks ={"mcl_core:diamondblock","mcl_core:ironblock","mcl_core:goldblock","mcl_core:emeraldblock","mcl_nether:netheriteblock"},
|
|
||||||
fuel = {"mcl_core:diamond","mcl_core:emerald","mcl_core:iron_ingot","mcl_core:gold_ingot","mcl_nether:netherite_ingot"}
|
|
||||||
}
|
|
||||||
local beacon_blocklist = mcl_beacons.blocks
|
|
||||||
local beacon_fuellist = mcl_beacons.fuel
|
|
||||||
|
|
||||||
local pallete_order = {
|
|
||||||
glass_cyan = 1,
|
|
||||||
pane_cyan_flat = 1,
|
|
||||||
pane_cyan = 1,
|
|
||||||
|
|
||||||
glass_white = 2,
|
|
||||||
pane_white_flat = 2,
|
|
||||||
pane_white = 2,
|
|
||||||
|
|
||||||
glass_brown = 3,
|
|
||||||
pane_brown_flat = 3,
|
|
||||||
pane_brown = 3,
|
|
||||||
|
|
||||||
glass_blue = 4,
|
|
||||||
pane_blue_flat = 4,
|
|
||||||
pane_blue = 4,
|
|
||||||
|
|
||||||
glass_light_blue = 5,
|
|
||||||
pane_light_blue_flat = 5,
|
|
||||||
pane_light_blue = 5,
|
|
||||||
|
|
||||||
glass_pink = 6,
|
|
||||||
pane_pink_flat = 6,
|
|
||||||
pane_pink = 6,
|
|
||||||
|
|
||||||
glass_purple = 7,
|
|
||||||
pane_purple_flat = 7,
|
|
||||||
pane_purple = 7,
|
|
||||||
|
|
||||||
glass_red = 8,
|
|
||||||
pane_red_flat = 8,
|
|
||||||
pane_red = 8,
|
|
||||||
|
|
||||||
glass_silver = 9,
|
|
||||||
pane_silver_flat = 9,
|
|
||||||
pane_silver = 9,
|
|
||||||
|
|
||||||
glass_gray = 10,
|
|
||||||
pane_gray_flat = 10,
|
|
||||||
pane_gray = 10,
|
|
||||||
|
|
||||||
glass_lime = 11,
|
|
||||||
pane_lime_flat = 11,
|
|
||||||
pane_lime = 11,
|
|
||||||
|
|
||||||
glass_green = 12,
|
|
||||||
pane_green_flat = 12,
|
|
||||||
pane_green = 12,
|
|
||||||
|
|
||||||
glass_orange = 13,
|
|
||||||
pane_orange_flat = 13,
|
|
||||||
pane_orange = 13,
|
|
||||||
|
|
||||||
glass_yellow = 14,
|
|
||||||
pane_yellow_flat = 14,
|
|
||||||
pane_yellow = 14,
|
|
||||||
|
|
||||||
glass_black = 15,
|
|
||||||
pane_black_flat = 15,
|
|
||||||
pane_black = 15,
|
|
||||||
|
|
||||||
glass_magenta = 16,
|
|
||||||
pane_magenta_flat = 16,
|
|
||||||
pane_magenta = 16
|
|
||||||
}
|
|
||||||
|
|
||||||
local function get_beacon_beam(glass_nodename)
|
|
||||||
if glass_nodename == "air" then return 0 end
|
|
||||||
local glass_string = glass_nodename:split(':')[2]
|
|
||||||
if not pallete_order[glass_string] then return 0 end
|
|
||||||
return pallete_order[glass_string]
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("mcl_beacons:beacon_beam", {
|
|
||||||
tiles = {"^[colorize:#b8bab9"},
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.1250, -0.5000, -0.1250, 0.1250, 0.5000, 0.1250}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pointable= false,
|
|
||||||
light_source = 14,
|
|
||||||
walkable = false,
|
|
||||||
groups = {not_in_creative_inventory=1},
|
|
||||||
_mcl_blast_resistance = 1200,
|
|
||||||
paramtype2 = "color",
|
|
||||||
palette = "beacon_beam_palette.png",
|
|
||||||
palette_index = 0,
|
|
||||||
buildable_to = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
mesecon.register_mvps_stopper("mcl_beacons:beacon_beam")
|
|
||||||
|
|
||||||
local formspec_string=
|
|
||||||
"size[11,14]"..
|
|
||||||
|
|
||||||
"label[4.5,0.5;"..minetest.formspec_escape(S("Beacon:")).."]"..
|
|
||||||
"label[0.5,1;"..minetest.formspec_escape(S("Primary Power:")).."]"..
|
|
||||||
"label[0.5,8.25;"..minetest.formspec_escape( S("Inventory:")).."]"..
|
|
||||||
|
|
||||||
"image[1,1.5;1,1;custom_beacom_symbol_4.png]"..
|
|
||||||
"image[1,3;1,1;custom_beacom_symbol_3.png]"..
|
|
||||||
"image[1,4.5;1,1;custom_beacom_symbol_2.png]"..
|
|
||||||
"image[1,6;1,1;custom_beacom_symbol_1.png]"..
|
|
||||||
|
|
||||||
"image_button[5.2,1.5;1,1;mcl_potions_effect_swift.png;swiftness;]"..
|
|
||||||
"image_button[5.2,3;1,1;mcl_potions_effect_leaping.png;leaping;]"..
|
|
||||||
"image_button[5.2,4.5;1,1;mcl_potions_effect_strong.png;strenght;]"..
|
|
||||||
"image_button[5.2,6;1,1;mcl_potions_effect_regenerating.png;regeneration;]"..
|
|
||||||
|
|
||||||
"item_image[1,7;1,1;mcl_core:diamond]"..
|
|
||||||
"item_image[2.2,7;1,1;mcl_core:emerald]"..
|
|
||||||
"item_image[3.4,7;1,1;mcl_core:iron_ingot]"..
|
|
||||||
"item_image[4.6,7;1,1;mcl_core:gold_ingot]"..
|
|
||||||
"item_image[5.8,7;1,1;mcl_nether:netherite_ingot]"..
|
|
||||||
|
|
||||||
mcl_formspec.get_itemslot_bg(7.2,7,1,1)..
|
|
||||||
"list[context;input;7.2,7;1,1;]"..
|
|
||||||
mcl_formspec.get_itemslot_bg(1,9,9,3)..
|
|
||||||
"list[current_player;main;1,9;9,3;9]"..
|
|
||||||
mcl_formspec.get_itemslot_bg(1,12.5,9,1)..
|
|
||||||
"list[current_player;main;1,12.5;9,1;]"
|
|
||||||
|
|
||||||
local function remove_beacon_beam(pos)
|
|
||||||
for y=pos.y, pos.y+301 do
|
|
||||||
local node = minetest.get_node({x=pos.x,y=y,z=pos.z})
|
|
||||||
if node.name ~= "air" and node.name ~= "mcl_core:bedrock" and node.name ~= "mcl_core:void" then
|
|
||||||
if node.name == "ignore" then
|
|
||||||
minetest.get_voxel_manip():read_from_map({x=pos.x,y=y,z=pos.z}, {x=pos.x,y=y,z=pos.z})
|
|
||||||
node = minetest.get_node({x=pos.x,y=y,z=pos.z})
|
|
||||||
end
|
|
||||||
|
|
||||||
if node.name == "mcl_beacons:beacon_beam" then
|
|
||||||
minetest.remove_node({x=pos.x,y=y,z=pos.z})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function beacon_blockcheck(pos)
|
|
||||||
for y_offset = 1,4 do
|
|
||||||
local block_y = pos.y - y_offset
|
|
||||||
for block_x = (pos.x-y_offset),(pos.x+y_offset) do
|
|
||||||
for block_z = (pos.z-y_offset),(pos.z+y_offset) do
|
|
||||||
local valid_block = false --boolean which stores if block is valid or not
|
|
||||||
for _, beacon_block in pairs(beacon_blocklist) do
|
|
||||||
if beacon_block == minetest.get_node({x=block_x,y=block_y,z=block_z}).name and not valid_block then --is the block in the pyramid a valid beacon block
|
|
||||||
valid_block =true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not valid_block then
|
|
||||||
return y_offset -1 --the last layer is complete, this one is missing or incomplete
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if y_offset == 4 then --all checks are done, beacon is maxed
|
|
||||||
return y_offset
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function effect_player(effect,pos,power_level, effect_level,player)
|
|
||||||
local distance = vector.distance(player:get_pos(), pos)
|
|
||||||
if distance > (power_level+1)*10 then return end
|
|
||||||
if effect == "swiftness" then
|
|
||||||
mcl_potions.swiftness_func(player,effect_level,16)
|
|
||||||
elseif effect == "leaping" then
|
|
||||||
mcl_potions.leaping_func(player, effect_level, 16)
|
|
||||||
elseif effect == "strenght" then
|
|
||||||
mcl_potions.strength_func(player, effect_level, 16)
|
|
||||||
elseif effect == "regeneration" then
|
|
||||||
mcl_potions.regeneration_func(player, effect_level, 16)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function globalstep_function(pos,player)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local power_level = beacon_blockcheck(pos)
|
|
||||||
local effect_string = meta:get_string("effect")
|
|
||||||
if meta:get_int("effect_level") == 2 and power_level < 4 then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
local obstructed = false
|
|
||||||
for y=pos.y+1, pos.y+100 do
|
|
||||||
|
|
||||||
local nodename = minetest.get_node({x=pos.x,y=y, z = pos.z}).name
|
|
||||||
if nodename ~= "mcl_core:bedrock" and nodename ~= "air" and nodename ~= "mcl_core:void" and nodename ~= "ignore" then --ignore means not loaded, let's just assume that's air
|
|
||||||
if nodename ~="mcl_beacons:beacon_beam" then
|
|
||||||
if minetest.get_item_group(nodename,"glass") == 0 and minetest.get_item_group(nodename,"material_glass") == 0 then
|
|
||||||
obstructed = true
|
|
||||||
remove_beacon_beam(pos)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if obstructed then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
effect_player(effect_string,pos,power_level,meta:get_int("effect_level"),player)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("mcl_beacons:beacon", {
|
|
||||||
description = S"Beacon",
|
|
||||||
drawtype = "mesh",
|
|
||||||
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
||||||
mesh = "mcl_beacon.b3d",
|
|
||||||
tiles = {"beacon_UV.png"},
|
|
||||||
use_texture_alpha = "clip",
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
inv:set_size("input", 1)
|
|
||||||
local form = formspec_string
|
|
||||||
meta:set_string("formspec", form)
|
|
||||||
end,
|
|
||||||
on_destruct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local input = meta:get_inventory():get_stack("input",1)
|
|
||||||
if not input:is_empty() then
|
|
||||||
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} --from mcl_anvils
|
|
||||||
minetest.add_item(p, input)
|
|
||||||
end
|
|
||||||
remove_beacon_beam(pos)
|
|
||||||
end,
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
|
||||||
if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght then
|
|
||||||
local sender_name = sender:get_player_name()
|
|
||||||
local power_level = beacon_blockcheck(pos)
|
|
||||||
if minetest.is_protected(pos, sender_name) then
|
|
||||||
minetest.record_protection_violation(pos, sender_name)
|
|
||||||
return
|
|
||||||
elseif power_level == 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local input = inv:get_stack("input",1)
|
|
||||||
|
|
||||||
if input:is_empty() then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local valid_item = false
|
|
||||||
|
|
||||||
for _, item in ipairs(beacon_fuellist) do
|
|
||||||
if input:get_name() == item then
|
|
||||||
valid_item = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not valid_item then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local successful = false
|
|
||||||
if fields.swiftness then
|
|
||||||
if power_level == 4 then
|
|
||||||
minetest.get_meta(pos):set_int("effect_level",2)
|
|
||||||
else
|
|
||||||
minetest.get_meta(pos):set_int("effect_level",1)
|
|
||||||
end
|
|
||||||
minetest.get_meta(pos):set_string("effect","swiftness")
|
|
||||||
successful = true
|
|
||||||
elseif fields.leaping and power_level >= 2 then
|
|
||||||
if power_level == 4 then
|
|
||||||
minetest.get_meta(pos):set_int("effect_level",2)
|
|
||||||
else
|
|
||||||
minetest.get_meta(pos):set_int("effect_level",1)
|
|
||||||
end
|
|
||||||
minetest.get_meta(pos):set_string("effect","leaping")
|
|
||||||
successful = true
|
|
||||||
elseif fields.strenght and power_level >= 3 then
|
|
||||||
if power_level == 4 then
|
|
||||||
minetest.get_meta(pos):set_int("effect_level",2)
|
|
||||||
else
|
|
||||||
minetest.get_meta(pos):set_int("effect_level",1)
|
|
||||||
end
|
|
||||||
minetest.get_meta(pos):set_string("effect","strenght")
|
|
||||||
successful = true
|
|
||||||
elseif fields.regeneration and power_level == 4 then
|
|
||||||
minetest.get_meta(pos):set_int("effect_level",2)
|
|
||||||
minetest.get_meta(pos):set_string("effect","regeneration")
|
|
||||||
successful = true
|
|
||||||
end
|
|
||||||
if successful then
|
|
||||||
if power_level == 4 then
|
|
||||||
awards.unlock(sender:get_player_name(),"mcl:maxed_beacon")
|
|
||||||
end
|
|
||||||
awards.unlock(sender:get_player_name(),"mcl:beacon")
|
|
||||||
input:take_item()
|
|
||||||
inv:set_stack("input",1,input)
|
|
||||||
|
|
||||||
local beam_palette_index = 0
|
|
||||||
remove_beacon_beam(pos)
|
|
||||||
for y = pos.y +1, pos.y + 201 do
|
|
||||||
local node = minetest.get_node({x=pos.x,y=y,z=pos.z})
|
|
||||||
if node.name == ignore then
|
|
||||||
minetest.get_voxel_manip():read_from_map({x=pos.x,y=y,z=pos.z}, {x=pos.x,y=y,z=pos.z})
|
|
||||||
node = minetest.get_node({x=pos.x,y=y,z=pos.z})
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if minetest.get_item_group(node.name, "glass") ~= 0 or minetest.get_item_group(node.name,"material_glass") ~= 0 then
|
|
||||||
beam_palette_index = get_beacon_beam(node.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
if node.name == "air" then
|
|
||||||
minetest.set_node({x=pos.x,y=y,z=pos.z},{name="mcl_beacons:beacon_beam",param2=beam_palette_index})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
globalstep_function(pos,sender)--call it once outside the globalstep so the player gets the effect right after selecting it
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
light_source = 14,
|
|
||||||
groups = {handy=1},
|
|
||||||
drop = "mcl_beacons:beacon",
|
|
||||||
sounds = mcl_sounds.node_sound_glass_defaults(),
|
|
||||||
_mcl_hardness = 3,
|
|
||||||
})
|
|
||||||
|
|
||||||
mesecon.register_mvps_stopper("mcl_beacons:beacon")
|
|
||||||
mcl_wip.register_wip_item("mcl_beacons:beacon")
|
|
||||||
|
|
||||||
function register_beaconblock (itemstring)--API function for other mods
|
|
||||||
table.insert(beacon_blocklist, itemstring)
|
|
||||||
end
|
|
||||||
|
|
||||||
function register_beaconfuel(itemstring)
|
|
||||||
table.insert(beacon_fuellist, itemstring)
|
|
||||||
end
|
|
||||||
|
|
||||||
local timer = 0
|
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
|
||||||
timer = timer + dtime
|
|
||||||
if timer >= 3 then
|
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
|
||||||
local player_pos = player:get_pos()
|
|
||||||
local pos_list = minetest.find_nodes_in_area({x=player_pos.x-50, y=player_pos.y-50, z=player_pos.z-50}, {x=player_pos.x+50, y=player_pos.y+50, z=player_pos.z+50},"mcl_beacons:beacon")
|
|
||||||
for _, pos in ipairs(pos_list) do
|
|
||||||
globalstep_function(pos,player)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
timer = 0
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_abm{
|
|
||||||
label="update beacon beam",
|
|
||||||
nodenames = {"mcl_beacons:beacon_beam"},
|
|
||||||
interval = 1,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos)
|
|
||||||
local node_below = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
|
|
||||||
local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
|
|
||||||
local node_current = minetest.get_node(pos)
|
|
||||||
|
|
||||||
if node_below.name == "air" then
|
|
||||||
if minetest.get_node({x=pos.x,y=pos.y-2,z=pos.z}).name == "mcl_beacons:beacon" then
|
|
||||||
minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z},{name="mcl_beacons:beacon_beam",param2=0})
|
|
||||||
end
|
|
||||||
remove_beacon_beam(pos)
|
|
||||||
elseif node_above.name == "air" or (node_above.name == "mcl_beacons:beacon_beam" and node_above.param2 ~= node_current.param2) then
|
|
||||||
minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z},{name="mcl_beacons:beacon_beam",param2=node_current.param2})
|
|
||||||
elseif minetest.get_item_group(node_above.name, "glass") ~= 0 or minetest.get_item_group(node_above.name,"material_glass") ~= 0 then
|
|
||||||
minetest.set_node({x=pos.x,y=pos.y+2,z=pos.z},{name="mcl_beacons:beacon_beam",param2=get_beacon_beam(node_above.name)})
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "mcl_beacons:beacon",
|
|
||||||
recipe = {
|
|
||||||
{"mcl_core:glass", "mcl_core:glass", "mcl_core:glass"},
|
|
||||||
{"mcl_core:glass", "mcl_mobitems:nether_star", "mcl_core:glass"},
|
|
||||||
{"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -1,5 +0,0 @@
|
||||||
# textdomain: mcl_beacons
|
|
||||||
Beacon=Leuchtfeuer
|
|
||||||
Beacon:=Leuchtfeuer:
|
|
||||||
Primary Power:=Primäre Kraft:
|
|
||||||
Inventory:=Inventar:
|
|
|
@ -1,5 +0,0 @@
|
||||||
# textdomain: mcl_beacons
|
|
||||||
Beacon=
|
|
||||||
Beacon:=
|
|
||||||
Primary Power:=
|
|
||||||
Inventory:=
|
|
|
@ -1,2 +0,0 @@
|
||||||
author=chmodsayshello
|
|
||||||
depends=mcl_formspec, mcl_init, mcl_wip, mesecons_mvps, mcl_core, mcl_sounds, awards, mcl_achievements, mcl_mobitems, mcl_nether
|
|
Before Width: | Height: | Size: 1014 B |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 624 B |
Before Width: | Height: | Size: 635 B |
Before Width: | Height: | Size: 635 B |
Before Width: | Height: | Size: 641 B |
Before Width: | Height: | Size: 635 B |
|
@ -37,7 +37,6 @@ Players in bed: @1/@2=Joueurs au lit: @1/@2
|
||||||
Note: Night skip is disabled.=Remarque: Le saut de nuit est désactivé.
|
Note: Night skip is disabled.=Remarque: Le saut de nuit est désactivé.
|
||||||
You're sleeping.=Tu dors.
|
You're sleeping.=Tu dors.
|
||||||
You will fall asleep when all players are in bed.=Vous vous endormirez lorsque tous les joueurs seront au lit.
|
You will fall asleep when all players are in bed.=Vous vous endormirez lorsque tous les joueurs seront au lit.
|
||||||
You will fall asleep when @1% of all players are in bed.=Vous vous endormirez lorsque @1% des joueurs seront au lit.
|
|
||||||
You're in bed.=Tu es au lit.
|
You're in bed.=Tu es au lit.
|
||||||
Allows you to sleep=Vous permet de dormir
|
Allows you to sleep=Vous permet de dormir
|
||||||
Respawn Anchor=Ancre de Réapparition
|
Respawn Anchor=Ancre de Réapparition
|
|
@ -245,16 +245,16 @@ minetest.register_node("mcl_blackstone:chain", {
|
||||||
|
|
||||||
--slabs/stairs
|
--slabs/stairs
|
||||||
|
|
||||||
mcl_stairs.register_stair_and_slab_simple("blackstone", "mcl_blackstone:blackstone", S("Blackstone Stair"), S("Blackstone Slab"), S("Double Blackstone Slab"))
|
mcl_stairs.register_stair_and_slab_simple("blackstone", "mcl_blackstone:blackstone", "Blackstone Stair", "Blackstone Slab", "Double Blackstone Slab")
|
||||||
|
|
||||||
|
|
||||||
mcl_stairs.register_stair_and_slab_simple("blackstone_polished", "mcl_blackstone:blackstone_polished", S("Polished Blackstone Stair"), S("Polished Blackstone Slab"), S("Polished Double Blackstone Slab"))
|
mcl_stairs.register_stair_and_slab_simple("blackstone_polished", "mcl_blackstone:blackstone_polished", "Polished Blackstone Stair", "Polished Blackstone Slab", "Polished Double Blackstone Slab")
|
||||||
|
|
||||||
|
|
||||||
mcl_stairs.register_stair_and_slab_simple("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished", S("Chiseled Polished Blackstone Stair"), S("Chiseled Polished Blackstone Slab"), S("Double Polished Chiseled Blackstone Slab"))
|
mcl_stairs.register_stair_and_slab_simple("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished", "Polished Chiseled Blackstone Stair", "Chiseled Polished Blackstone Slab", "Double Polished Chiseled Blackstone Slab")
|
||||||
|
|
||||||
|
|
||||||
mcl_stairs.register_stair_and_slab_simple("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished", S("Polished Blackstone Brick Stair"), S("Polished Blackstone Brick Slab"), S("Double Polished Blackstone Brick Slab"))
|
mcl_stairs.register_stair_and_slab_simple("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished", "Polished Blackstone Brick Stair", "Polished Blackstone Brick Slab", "Double Polished Blackstone Brick Slab")
|
||||||
|
|
||||||
--Wall
|
--Wall
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
# textdomain: mcl_blackstone
|
# textdomain: mcl_blackstone
|
||||||
Blackstone=Roche noire
|
Blackstone=Roche noire
|
||||||
Polished Blackstone=Pierre noire
|
Polished Blackstone=Pierre noire
|
||||||
Chiseled Polished Blackstone=Pierre noire sculptée
|
Chieseled Polished Blackstone=Pierre noire sculptée
|
||||||
Polished Blackstone Bricks=Briques de pierre noire
|
Polished Blackstone Bricks=Briques de pierre noire
|
||||||
Basalt=Basalte
|
Basalt=Basalte
|
||||||
Polished Basalt=Basalte taillé
|
Polished Basalt=Basalte taillé
|
||||||
Blackstone Slab=Dalle de roche noire
|
Blackstone Slab=Dalle de roche noire
|
||||||
Polished Blackstone Slab=Dalle de pierre noire
|
Polished Blackstone Slab=Dalle de pierre noire
|
||||||
Chiseled Polished Blackstone Slab=Dalle de pierre noire sculptée
|
Chieseled Polished Blackstone Slab=Dalle de pierre noire sculptée
|
||||||
Polished Blackstone Brick Slab=Dalle de briques de pierre noire
|
Polished Blackstone Brick Slab=Dalle de briques de pierre noire
|
||||||
Blackstone Stair=Escalier de roche noire
|
Blackstone Stairs=Escalier de roche noire
|
||||||
Polished Blackstone Stair=Escalier de pierre noire
|
Polished Blackstone Stairs=Escalier de pierre noire
|
||||||
Chiseled Polished Blackstone Stair=Escalier de pierre noire sculptée
|
Chieseled Polished Blackstone Stairs=Escalier de pierre noire sculptée
|
||||||
Polished Blackstone Brick Stair=Escalier de briques de pierre noire
|
Polished Blackstone Brick Stairs=Escalier de briques de pierre noire
|
||||||
Quartz Bricks=Briques de quartz
|
Quartz Bricks=Briques de quartz
|
||||||
Soul Torch=Torche des âmes
|
Soul Torch=Torche des âmes
|
||||||
Soul Lantern=Lanterne des âmes
|
Soul Lantern=Lanterne des âmes
|
||||||
|
@ -21,8 +21,3 @@ Eternal Soul Fire=Feux éternel des âmes
|
||||||
Gilded Blackstone=Roche noire dorée
|
Gilded Blackstone=Roche noire dorée
|
||||||
Nether Gold Ore=Minerai d'or du Nether
|
Nether Gold Ore=Minerai d'or du Nether
|
||||||
Smooth Basalt=Basalte lisse
|
Smooth Basalt=Basalte lisse
|
||||||
Blackstone Wall=Muret de Roche noire
|
|
||||||
Double Blackstone Slab=Double dalle de roche noire
|
|
||||||
Polished Double Blackstone Slab=Double dalle de pierre noire
|
|
||||||
Double Polished Chiseled Blackstone Slab=Double dalle de pierre noire sculptée
|
|
||||||
Double Polished Blackstone Brick Slab=Double dalle de briques de pierre noire
|
|
|
@ -7,12 +7,12 @@ Basalt=
|
||||||
Polished Basalt=
|
Polished Basalt=
|
||||||
Blackstone Slab=
|
Blackstone Slab=
|
||||||
Polished Blackstone Slab=
|
Polished Blackstone Slab=
|
||||||
Chiseled Polished Blackstone Slab=
|
Chieseled Polished Blackstone Slab=
|
||||||
Polished Blackstone Brick Slab=
|
Polished Blackstone Brick Slab=
|
||||||
Blackstone Stair=
|
Blackstone Stairs=
|
||||||
Polished Blackstone Stair=
|
Polished Blackstone Stairs=
|
||||||
Chiseled Polished Blackstone Stair=
|
Chieseled Polished Blackstone Stairs=
|
||||||
Polished Blackstone Brick Stair=
|
Polished Blackstone Brick Stairs=
|
||||||
Quartz Bricks=
|
Quartz Bricks=
|
||||||
Soul Torch=
|
Soul Torch=
|
||||||
Soul Lantern=
|
Soul Lantern=
|
||||||
|
@ -22,7 +22,3 @@ Gilded Blackstone=
|
||||||
Nether Gold Ore=
|
Nether Gold Ore=
|
||||||
Smooth Basalt=
|
Smooth Basalt=
|
||||||
Blackstone Wall=
|
Blackstone Wall=
|
||||||
Double Blackstone Slab=
|
|
||||||
Polished Double Blackstone Slab=
|
|
||||||
Double Polished Chiseled Blackstone Slab=
|
|
||||||
Double Polished Blackstone Brick Slab=
|
|