forked from MineClone5/MineClone5
Update Fork #9
|
@ -70,7 +70,11 @@ an explanation.
|
|||
|
||||
## Installation
|
||||
This game requires latest stable [Minetest](http://minetest.net) to run, please install
|
||||
it first. Only stable versions of Minetest are officially supported.
|
||||
it first. Only latest stable version of Minetest is 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.
|
||||
|
||||
To install MineClone 5 (if you haven't already), move this directory into the
|
||||
|
|
|
@ -148,16 +148,48 @@ local chunk_scan_range = {
|
|||
[ 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 center = vector.add(minp, HALF_CS_NODES)
|
||||
for check_x = center.x - CS_NODES, center.x + CS_NODES, CS_NODES do
|
||||
for check_y = center.y - CS_NODES, center.y + CS_NODES, CS_NODES do
|
||||
for check_z = center.z - CS_NODES, center.z + CS_NODES, CS_NODES do
|
||||
local pos = vector.new(check_x, check_y, check_z)
|
||||
if pos ~= center then
|
||||
minetest_get_voxel_manip():read_from_map(pos, pos)
|
||||
local node = minetest_get_node(pos)
|
||||
local center_x = minp.x + HALF_CS_NODES
|
||||
local center_y = minp.y + HALF_CS_NODES
|
||||
local center_z = minp.z + HALF_CS_NODES
|
||||
local from_x = center_x - CS_NODES
|
||||
local from_y = center_y - CS_NODES
|
||||
local from_z = center_z - CS_NODES
|
||||
local to_x = center_x + CS_NODES
|
||||
local to_y = center_y + CS_NODES
|
||||
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
|
||||
-- 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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
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*.
|
||||
function table.update(t, ...)
|
||||
for _, to in ipairs{...} do
|
||||
|
@ -33,36 +39,6 @@ function mcl_util.rotate_axis(itemstack, placer, pointed_thing)
|
|||
return itemstack
|
||||
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
|
||||
-- returns the slot of the first item which matches a condition.
|
||||
-- Returns nil if no item was found.
|
||||
|
@ -87,7 +63,7 @@ end
|
|||
|
||||
-- Returns true if itemstack is a shulker box
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -133,136 +109,116 @@ 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)
|
||||
--- destination_list (optional): List name of the destination inventory. Default is normally "main"; "src" for furnace
|
||||
-- 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)
|
||||
local dpos = table.copy(destination_pos)
|
||||
local spos = table.copy(source_pos)
|
||||
local snode = minetest.get_node(spos)
|
||||
local dnode = minetest.get_node(dpos)
|
||||
|
||||
local dctype = minetest.get_item_group(dnode.name, "container")
|
||||
local sctype = minetest.get_item_group(snode.name, "container")
|
||||
|
||||
-- Container type 7 does not allow any movement
|
||||
if sctype == 7 then
|
||||
return false
|
||||
end
|
||||
|
||||
-- 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
|
||||
local spos = table_copy(source_pos)
|
||||
local snode = minetest_get_node(spos)
|
||||
local sctype = minetest_get_item_group(snode.name, "container")
|
||||
local default_source_list = CONTAINER_GROUP_TO_LIST[sctype]
|
||||
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
|
||||
return pos, node, ctype
|
||||
snode = minetest_get_node(spos)
|
||||
sctype = minetest_get_item_group(snode.name, "container")
|
||||
if sctype ~= DOUBLE_CHEST_LEFT then return end
|
||||
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 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 dnode = minetest_get_node(dpos)
|
||||
local dctype = minetest_get_item_group(dnode.name, "container")
|
||||
local default_destination_list = CONTAINER_GROUP_TO_LIST[sctype]
|
||||
if not default_destination_list then return end
|
||||
if dctype == DOUBLE_CHEST_RIGHT 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_LEFT then return end
|
||||
end
|
||||
local dmeta = minetest_get_meta(dpos)
|
||||
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
|
||||
if not source_stack_id then
|
||||
source_stack_id = -1
|
||||
end
|
||||
local source_stack_id = source_stack_id or -1
|
||||
if source_stack_id == -1 then
|
||||
local cond = nil
|
||||
-- Prevent shulker box inception
|
||||
if dctype == 3 then
|
||||
cond = is_not_shulker_box
|
||||
end
|
||||
if dctype == SHULKER_BOX then cond = is_not_shulker_box end
|
||||
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
|
||||
if not source_stack_id then
|
||||
-- Try again if source is a double container
|
||||
if sctype == 5 then
|
||||
spos = mcl_util.get_double_container_neighbor_pos(spos, snode.param2, "left")
|
||||
smeta = minetest.get_meta(spos)
|
||||
sinv = smeta:get_inventory()
|
||||
|
||||
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
|
||||
if not source_stack_id then
|
||||
return false
|
||||
if sctype == DOUBLE_CHEST_LEFT 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
|
||||
else
|
||||
return false
|
||||
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()
|
||||
source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond)
|
||||
end
|
||||
end
|
||||
if not source_stack_id then return end
|
||||
end
|
||||
|
||||
-- Abort transfer if shulker box wants to go into shulker box
|
||||
if dctype == 3 then
|
||||
if dctype == SHULKER_BOX then
|
||||
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 false
|
||||
end
|
||||
end
|
||||
-- Container type 7 does not allow any placement
|
||||
if dctype == 7 then
|
||||
return false
|
||||
if stack and minetest_get_item_group(stack:get_name(), "shulker_box") == 1 then return end
|
||||
end
|
||||
|
||||
-- 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"
|
||||
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
|
||||
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
|
||||
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
|
||||
return false
|
||||
-- Update furnace
|
||||
if ok and dctype == FURNACE 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
|
||||
|
||||
-- Returns the ID of the first non-empty slot in the given inventory list
|
||||
|
@ -292,7 +248,7 @@ function mcl_util.generate_on_place_plant_function(condition)
|
|||
end
|
||||
|
||||
-- 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 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
|
||||
|
@ -300,8 +256,8 @@ function mcl_util.generate_on_place_plant_function(condition)
|
|||
end
|
||||
|
||||
local place_pos
|
||||
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_under = minetest.registered_nodes[minetest_get_node(pointed_thing.under).name]
|
||||
local def_above = minetest.registered_nodes[minetest_get_node(pointed_thing.above).name]
|
||||
if not def_under or not def_above then
|
||||
return itemstack
|
||||
end
|
||||
|
@ -359,7 +315,7 @@ function mcl_util.call_on_rightclick(itemstack, player, pointed_thing)
|
|||
-- Call on_rightclick if the pointed node defines it
|
||||
if pointed_thing and pointed_thing.type == "node" then
|
||||
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
|
||||
local nodedef = minetest.registered_nodes[node.name]
|
||||
local on_rightclick = nodedef and nodedef.on_rightclick
|
||||
|
@ -372,7 +328,7 @@ end
|
|||
|
||||
function mcl_util.calculate_durability(itemstack)
|
||||
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
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ local function land_state_switch(self, dtime)
|
|||
end
|
||||
|
||||
--ignore everything else if following
|
||||
if mobs.check_following(self) and
|
||||
if mobs.check_following(self, dtime) and
|
||||
(not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) and
|
||||
(not self.breed_timer or (self.breed_timer and self.breed_timer == 0)) then
|
||||
self.state = "follow"
|
||||
|
@ -984,7 +984,7 @@ function mobs.mob_step(self, dtime)
|
|||
|
||||
--go get the closest player
|
||||
if attacking then
|
||||
|
||||
mobs.do_head_logic(self, dtime, attacking)
|
||||
self.memory = 6 --6 seconds of memory
|
||||
|
||||
--set initial punch timer
|
||||
|
@ -1040,6 +1040,7 @@ function mobs.mob_step(self, dtime)
|
|||
--don't break eye contact
|
||||
if self.hostile and self.attacking then
|
||||
mobs.set_yaw_while_attacking(self)
|
||||
mobs.do_head_logic(self, dtime, self.attacking)
|
||||
end
|
||||
|
||||
--perfectly reset pause_timer
|
||||
|
|
|
@ -3,7 +3,7 @@ local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
|
|||
local vector = vector
|
||||
|
||||
--check to see if someone nearby has some tasty food
|
||||
mobs.check_following = function(self) -- returns true or false
|
||||
mobs.check_following = function(self, dtime) -- returns true or false
|
||||
--ignore
|
||||
if not self.follow then
|
||||
self.following_person = nil
|
||||
|
@ -15,6 +15,7 @@ mobs.check_following = function(self) -- returns true or false
|
|||
|
||||
--check if the follower is a player incase they log out
|
||||
if follower and follower:is_player() then
|
||||
mobs.do_head_logic(self, dtime, follower)
|
||||
local stack = follower:get_wielded_item()
|
||||
--safety check
|
||||
if not stack then
|
||||
|
|
|
@ -6,9 +6,9 @@ local degrees = function(yaw)
|
|||
return yaw*180.0/math.pi
|
||||
end
|
||||
|
||||
mobs.do_head_logic = function(self,dtime)
|
||||
mobs.do_head_logic = function(self, dtime, player)
|
||||
|
||||
local player = minetest.get_player_by_name("singleplayer")
|
||||
local player = player or minetest.get_player_by_name("singleplayer")
|
||||
|
||||
local look_at = player:get_pos()
|
||||
look_at.y = look_at.y + player:get_properties().eye_height
|
||||
|
@ -89,10 +89,21 @@ mobs.do_head_logic = function(self,dtime)
|
|||
head_pitch = head_pitch + self.head_pitch_modifier
|
||||
end
|
||||
|
||||
if self.swap_y_with_x then
|
||||
self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),degrees(head_yaw),0))
|
||||
local head_bone = self.head_bone
|
||||
if (type(head_bone) == "table") then
|
||||
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
|
||||
self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),0,degrees(head_yaw)))
|
||||
if self.swap_y_with_x then
|
||||
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
|
||||
--set_bone_position([bone, position, rotation])
|
||||
end
|
Binary file not shown.
|
@ -82,7 +82,7 @@ mobs:register_mob("mobs_mc:sheep", {
|
|||
|
||||
--head code
|
||||
has_head = true,
|
||||
head_bone = "head",
|
||||
head_bone = {"hea1", "hea2",},
|
||||
|
||||
swap_y_with_x = false,
|
||||
reverse_head_yaw = false,
|
||||
|
|
|
@ -611,11 +611,14 @@ do
|
|||
io.close(file)
|
||||
if string then
|
||||
local savetable = minetest.deserialize(string)
|
||||
for name, players_stored_data in pairs(savetable.players_stored_data) do
|
||||
doc.data.players[name] = {}
|
||||
doc.data.players[name].stored_data = players_stored_data
|
||||
local savetable_players_stored_data = savetable and savetable.players_stored_data
|
||||
if savetable_players_stored_data then
|
||||
for name, players_stored_data in pairs(savetable_players_stored_data) do
|
||||
doc.data.players[name] = {}
|
||||
doc.data.players[name].stored_data = players_stored_data
|
||||
end
|
||||
minetest.log("action", "[doc] doc.mt successfully read.")
|
||||
end
|
||||
minetest.log("action", "[doc] doc.mt successfully read.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ Alexander Minges
|
|||
aligator
|
||||
ArTee3
|
||||
Artem Arbatsky
|
||||
balazsszalab
|
||||
basxto
|
||||
Benjamin Schötz
|
||||
Blue Blancmange
|
||||
|
@ -13,6 +14,7 @@ Booglejr
|
|||
Brandon
|
||||
Bu-Gee
|
||||
bzoss
|
||||
CableGuy67
|
||||
chmodsayshello
|
||||
Code-Sploit
|
||||
cora
|
||||
|
@ -31,6 +33,7 @@ Emojigit
|
|||
epCode
|
||||
erlehmann
|
||||
FinishedFragment
|
||||
FlamingRCCars
|
||||
Glaucos Ginez
|
||||
Gustavo Ramos Rehermann
|
||||
Guy Liner
|
||||
|
@ -39,6 +42,7 @@ HimbeerserverDE
|
|||
iliekprogrammar
|
||||
j1233
|
||||
Jared Moody
|
||||
Johannes Fritz
|
||||
jordan4ibanez
|
||||
kabou
|
||||
kay27
|
||||
|
@ -46,13 +50,14 @@ Laurent Rocher
|
|||
Li0n
|
||||
marcin-serwin
|
||||
Marcin Serwin
|
||||
Mark Roth
|
||||
Mental-Inferno
|
||||
Midgard
|
||||
MysticTempest
|
||||
Nicholas Niro
|
||||
nickolas360
|
||||
Nicu
|
||||
nikolaus-albinger
|
||||
Niklp
|
||||
Nils Dagsson Moskopp
|
||||
NO11
|
||||
NO411
|
||||
|
@ -60,6 +65,7 @@ Oil_boi
|
|||
pitchum
|
||||
PrairieAstronomer
|
||||
PrairieWind
|
||||
River River
|
||||
Rocher Laurent
|
||||
rootyjr
|
||||
Rootyjr
|
||||
|
@ -68,6 +74,7 @@ Sab Pyrope
|
|||
Saku Laesvuori
|
||||
sfan5
|
||||
SmallJoker
|
||||
Sumyjkl
|
||||
superfloh247
|
||||
Sven792
|
||||
Sydney Gems
|
||||
|
@ -75,6 +82,7 @@ talamh
|
|||
TechDudie
|
||||
Thinking
|
||||
Tianyang Zhang
|
||||
unknown
|
||||
U.N.Owen
|
||||
Wouters Dorian
|
||||
wuniversales
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
Please run the following command to update contributor list:
|
||||
|
||||
```bash
|
||||
# git log --pretty="%an" | sort | uniq >CONTRUBUTOR_LIST.txt
|
||||
```
|
||||
Please run `./update_credits.sh` from [tools](../../../tools) folder to update contributor list.
|
||||
|
||||
Please check that there is no error on execution, and `CONTRUBUTOR_LIST.txt` is updated.
|
||||
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
local refresh_interval = .63
|
||||
local huds = {}
|
||||
local default_debug = 3
|
||||
local default_debug = 5
|
||||
local after = minetest.after
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
local get_biome_name = minetest.get_biome_name
|
||||
local get_biome_data = minetest.get_biome_data
|
||||
local get_node = minetest.get_node
|
||||
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 = 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
|
||||
local CS = mcl_mapgen.CS_NODES
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
@ -17,6 +23,7 @@ local storage = minetest.get_mod_storage()
|
|||
local player_dbg = minetest.deserialize(storage:get_string("player_dbg") or "return {}") or {}
|
||||
|
||||
local function get_text(pos, bits)
|
||||
local pos = pos
|
||||
local bits = bits
|
||||
if bits == 0 then return "" end
|
||||
local y = pos.y
|
||||
|
@ -27,16 +34,42 @@ local function get_text(pos, bits)
|
|||
elseif y >= min2 and y <= max2 then
|
||||
y = y - min2
|
||||
end
|
||||
local biome_data = get_biome_data(pos)
|
||||
local biome_name = biome_data and get_biome_name(biome_data.biome) or "No biome"
|
||||
local text
|
||||
if bits == 1 then
|
||||
text = biome_name
|
||||
elseif bits == 2 then
|
||||
text = format("x:%.1f y:%.1f z:%.1f", pos.x, y, pos.z)
|
||||
elseif bits == 3 then
|
||||
text = format("%s x:%.1f y:%.1f z:%.1f", biome_name, pos.x, y, pos.z)
|
||||
|
||||
local will_show_mapgen_status = bits % 8 > 3
|
||||
local will_show_coordinates = bits % 4 > 1
|
||||
local will_show_biome_name = bits % 2 > 0
|
||||
local will_be_shown = {}
|
||||
|
||||
if will_show_biome_name then
|
||||
local biome_data = get_biome_data(pos)
|
||||
local biome_name = biome_data and get_biome_name(biome_data.biome) or "No biome"
|
||||
will_be_shown[#will_be_shown + 1] = biome_name
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -82,11 +115,11 @@ minetest.register_on_authplayer(function(name, ip, is_success)
|
|||
end)
|
||||
|
||||
minetest.register_chatcommand("debug",{
|
||||
description = S("Set debug bit mask: 0 = disable, 1 = biome name, 2 = coordinates, 3 = all"),
|
||||
description = S("Set debug bit mask: 0 = disable, 1 = biome name, 2 = coordinates, 4 = mapgen status, 7 = all"),
|
||||
func = function(name, params)
|
||||
local dbg = math.floor(tonumber(params) or default_debug)
|
||||
if dbg < 0 or dbg > 3 then
|
||||
minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 3))
|
||||
if dbg < 0 or dbg > 7 then
|
||||
minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 7))
|
||||
return
|
||||
end
|
||||
if dbg == default_debug then
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# textdomain: mcl_info
|
||||
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=
|
||||
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=
|
||||
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
|
||||
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 3 @= всё
|
||||
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 4 @= mapgen status, 7 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 4 @= состояние мапгена, 7 @= всё
|
||||
Error! Possible values are integer numbers from @1 to @2=Ошибка! Допустимые значения - целые числа от @1 до @2
|
||||
Debug bit mask set to @1=Отладочной битовой маске присвоено значение @1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# textdomain: mcl_info
|
||||
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=
|
||||
Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 4 @= mapgen status, 7 @= all=
|
||||
Error! Possible values are integer numbers from @1 to @2=
|
||||
Debug bit mask set to @1=
|
||||
|
|
|
@ -18,6 +18,30 @@ local entity_animations = {
|
|||
}
|
||||
}
|
||||
|
||||
-- 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"
|
||||
local function get_double_container_neighbor_pos(pos, param2, side)
|
||||
local pos = pos
|
||||
local param2 = param2
|
||||
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
|
||||
|
||||
minetest.register_entity("mcl_chests:chest", {
|
||||
initial_properties = {
|
||||
visual = "mesh",
|
||||
|
@ -217,14 +241,14 @@ local function chest_update_after_close(pos)
|
|||
find_or_create_entity(pos, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
||||
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
||||
|
||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_right", param2 = node.param2})
|
||||
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
|
||||
elseif node.name == "mcl_chests:trapped_chest_on_right" then
|
||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_right", param2 = node.param2})
|
||||
mesecon.receptor_off(pos, trapped_chest_mesecons_rules)
|
||||
|
||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2})
|
||||
find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left")
|
||||
mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules)
|
||||
|
@ -438,15 +462,15 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
-- BEGIN OF LISTRING WORKAROUND
|
||||
inv:set_size("input", 1)
|
||||
-- END OF LISTRING WORKAROUND
|
||||
if minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "right")).name == "mcl_chests:"..canonical_basename.."_small" then
|
||||
if minetest.get_node(get_double_container_neighbor_pos(pos, param2, "right")).name == "mcl_chests:"..canonical_basename.."_small" then
|
||||
minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_right",param2=param2})
|
||||
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right")
|
||||
local p = get_double_container_neighbor_pos(pos, param2, "right")
|
||||
minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_left", param2 = param2 })
|
||||
create_entity(p, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest")
|
||||
elseif minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "left")).name == "mcl_chests:"..canonical_basename.."_small" then
|
||||
elseif minetest.get_node(get_double_container_neighbor_pos(pos, param2, "left")).name == "mcl_chests:"..canonical_basename.."_small" then
|
||||
minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_left",param2=param2})
|
||||
create_entity(pos, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest")
|
||||
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left")
|
||||
local p = get_double_container_neighbor_pos(pos, param2, "left")
|
||||
minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_right", param2 = param2 })
|
||||
else
|
||||
minetest.swap_node(pos, { name = "mcl_chests:"..canonical_basename.."_small", param2 = param2 })
|
||||
|
@ -541,7 +565,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
on_construct = function(pos)
|
||||
local n = minetest.get_node(pos)
|
||||
local param2 = n.param2
|
||||
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left")
|
||||
local p = get_double_container_neighbor_pos(pos, param2, "left")
|
||||
if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_right" then
|
||||
n.name = "mcl_chests:"..canonical_basename.."_small"
|
||||
minetest.swap_node(pos, n)
|
||||
|
@ -560,7 +584,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
close_forms(canonical_basename, pos)
|
||||
|
||||
local param2 = n.param2
|
||||
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left")
|
||||
local p = get_double_container_neighbor_pos(pos, param2, "left")
|
||||
if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_right" then
|
||||
return
|
||||
end
|
||||
|
@ -581,7 +605,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
-- BEGIN OF LISTRING WORKAROUND
|
||||
elseif listname == "input" then
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left")
|
||||
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left")
|
||||
local other_inv = minetest.get_inventory({type="node", pos=other_pos})
|
||||
return limit_put(stack, inv, other_inv)
|
||||
--[[if inv:room_for_item("main", stack) then
|
||||
|
@ -609,7 +633,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
-- BEGIN OF LISTRING WORKAROUND
|
||||
if listname == "input" then
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left")
|
||||
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left")
|
||||
local other_inv = minetest.get_inventory({type="node", pos=other_pos})
|
||||
|
||||
inv:set_stack("input", 1, nil)
|
||||
|
@ -626,7 +650,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
_mcl_hardness = 2.5,
|
||||
|
||||
on_rightclick = function(pos, node, clicker)
|
||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||
local above_def = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name]
|
||||
local above_def_other = minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name]
|
||||
|
||||
|
@ -692,7 +716,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
on_construct = function(pos)
|
||||
local n = minetest.get_node(pos)
|
||||
local param2 = n.param2
|
||||
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right")
|
||||
local p = get_double_container_neighbor_pos(pos, param2, "right")
|
||||
if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_left" then
|
||||
n.name = "mcl_chests:"..canonical_basename.."_small"
|
||||
minetest.swap_node(pos, n)
|
||||
|
@ -710,7 +734,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
close_forms(canonical_basename, pos)
|
||||
|
||||
local param2 = n.param2
|
||||
local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right")
|
||||
local p = get_double_container_neighbor_pos(pos, param2, "right")
|
||||
if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_left" then
|
||||
return
|
||||
end
|
||||
|
@ -730,7 +754,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
return 0
|
||||
-- BEGIN OF LISTRING WORKAROUND
|
||||
elseif listname == "input" then
|
||||
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right")
|
||||
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right")
|
||||
local other_inv = minetest.get_inventory({type="node", pos=other_pos})
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
--[[if other_inv:room_for_item("main", stack) then
|
||||
|
@ -757,7 +781,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
" moves stuff to chest at "..minetest.pos_to_string(pos))
|
||||
-- BEGIN OF LISTRING WORKAROUND
|
||||
if listname == "input" then
|
||||
local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right")
|
||||
local other_pos = get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right")
|
||||
local other_inv = minetest.get_inventory({type="node", pos=other_pos})
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
|
||||
|
@ -775,7 +799,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile
|
|||
_mcl_hardness = 2.5,
|
||||
|
||||
on_rightclick = function(pos, node, clicker)
|
||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||
if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1
|
||||
or minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name].groups.opaque == 1 then
|
||||
-- won't open if there is no space from the top
|
||||
|
@ -892,12 +916,12 @@ register_chest("trapped_chest",
|
|||
find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left")
|
||||
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
||||
|
||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "left")
|
||||
minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2})
|
||||
mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules)
|
||||
end,
|
||||
function(pos, node, clicker)
|
||||
local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||
local pos_other = get_double_container_neighbor_pos(pos, node.param2, "right")
|
||||
|
||||
minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2})
|
||||
mesecon.receptor_on(pos, trapped_chest_mesecons_rules)
|
||||
|
|
|
@ -63,40 +63,42 @@ local function add_wear(placer, itemstack)
|
|||
end
|
||||
|
||||
local function anti_oxidation(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then return end
|
||||
local pointed_thing = pointed_thing
|
||||
if pointed_thing.type ~= "node" then return end
|
||||
|
||||
local node = minetest.get_node(pointed_thing.under)
|
||||
local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
|
||||
local pointed_thing_under = pointed_thing.under
|
||||
local node = minetest.get_node(pointed_thing_under)
|
||||
local node_def = minetest.registered_nodes[node.name]
|
||||
if not node_def then return end
|
||||
|
||||
if not placer:get_player_control().sneak and noddef.on_rightclick then
|
||||
return minetest.item_place(itemstack, placer, pointed_thing)
|
||||
end
|
||||
if not placer:get_player_control().sneak and node_def.on_rightclick then
|
||||
return minetest.item_place(itemstack, placer, pointed_thing)
|
||||
end
|
||||
|
||||
if minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
|
||||
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
|
||||
return itemstack
|
||||
end
|
||||
local placer_name = placer:get_player_name()
|
||||
if minetest.is_protected(pointed_thing_under, placer_name) then
|
||||
minetest.record_protection_violation(pointed_thing_under, placer_name)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
if noddef._mcl_stripped_variant == nil then
|
||||
if not node_def._mcl_stripped_variant then
|
||||
for _, c in pairs(stairs) do
|
||||
if noddef.name == "mcl_stairs:"..c[1].."_copper_"..c[2].."_cut"..c[3] then
|
||||
minetest.swap_node(pointed_thing.under, {name="mcl_stairs:"..c[1].."_copper_"..c[4], param2=node.param2})
|
||||
if node_def.name == "mcl_stairs:"..c[1].."_copper_"..c[2].."_cut"..c[3] then
|
||||
minetest.swap_node(pointed_thing_under, {name="mcl_stairs:"..c[1].."_copper_"..c[4], param2=node.param2})
|
||||
anti_oxidation_particles(pointed_thing)
|
||||
add_wear(placer, itemstack)
|
||||
end
|
||||
end
|
||||
if noddef._mcl_anti_oxidation_variant ~= nil then
|
||||
minetest.swap_node(pointed_thing.under, {name=noddef._mcl_anti_oxidation_variant, param2=node.param2})
|
||||
if node_def._mcl_anti_oxidation_variant then
|
||||
minetest.swap_node(pointed_thing_under, {name=node_def._mcl_anti_oxidation_variant, param2=node.param2})
|
||||
anti_oxidation_particles(pointed_thing)
|
||||
add_wear(placer, itemstack)
|
||||
end
|
||||
elseif noddef._mcl_stripped_variant ~= nil then
|
||||
minetest.swap_node(pointed_thing.under, {name=noddef._mcl_stripped_variant, param2=node.param2})
|
||||
elseif node_def._mcl_stripped_variant then
|
||||
minetest.swap_node(pointed_thing_under, {name=node_def._mcl_stripped_variant, param2=node.param2})
|
||||
add_wear(placer, itemstack)
|
||||
else
|
||||
return itemstack
|
||||
end
|
||||
return itemstack
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local function register_axe_override(axe_name)
|
||||
|
|
|
@ -4,11 +4,21 @@
|
|||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
local mg_name = mcl_mapgen.name
|
||||
local v6 = mcl_mapgen.v6
|
||||
|
||||
local math = math
|
||||
local vector = vector
|
||||
local math_random = math.random
|
||||
local minetest_after = minetest.after
|
||||
local minetest_get_node = minetest.get_node
|
||||
local minetest_get_node_drops = minetest.get_node_drops
|
||||
local minetest_get_node_or_nil = minetest.get_node_or_nil
|
||||
local minetest_get_node_light = minetest.get_node_light
|
||||
local minetest_get_item_group = minetest.get_item_group
|
||||
local mcl_time_get_number_of_times_at_pos = mcl_time.get_number_of_times_at_pos
|
||||
local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||
local minetest_registered_nodes = minetest.registered_nodes
|
||||
|
||||
local mg_name = mcl_mapgen.name
|
||||
local v6 = mcl_mapgen.v6
|
||||
|
||||
local OAK_TREE_ID = 1
|
||||
local DARK_OAK_TREE_ID = 2
|
||||
|
@ -26,11 +36,11 @@ minetest.register_abm({
|
|||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local water = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, "group:water")
|
||||
|
||||
local lavatype = minetest.registered_nodes[node.name].liquidtype
|
||||
local lavatype = minetest_registered_nodes[node.name].liquidtype
|
||||
|
||||
for w=1, #water do
|
||||
--local waternode = minetest.get_node(water[w])
|
||||
--local watertype = minetest.registered_nodes[waternode.name].liquidtype
|
||||
--local waternode = minetest_get_node(water[w])
|
||||
--local watertype = minetest_registered_nodes[waternode.name].liquidtype
|
||||
-- Lava on top of water: Water turns into stone
|
||||
if water[w].y < pos.y and water[w].x == pos.x and water[w].z == pos.z then
|
||||
minetest.set_node(water[w], {name="mcl_core:stone"})
|
||||
|
@ -72,11 +82,48 @@ local lava_spark_census = 0
|
|||
|
||||
function mcl_core.lava_spark_set_chance()
|
||||
lava_spark_chance = lava_spark_limit / lava_spark_abm_census
|
||||
minetest.after(LAVA_SPARK_ABM_INTERVAL, mcl_core.lava_spark_set_chance)
|
||||
minetest_after(LAVA_SPARK_ABM_INTERVAL, mcl_core.lava_spark_set_chance)
|
||||
lava_spark_abm_census = 0
|
||||
lava_spark_census = 0
|
||||
end
|
||||
|
||||
function lava_spark_add(pos)
|
||||
local node = minetest_get_node(pos)
|
||||
if minetest_get_item_group(node.name, "lava") == 0 then return end
|
||||
|
||||
local above = minetest_get_node(vector.new(pos.x, pos.y + 1, pos.z))
|
||||
if above.name ~= "air" then return end
|
||||
|
||||
local pos_addend = vector.new(
|
||||
(math_random() - 0.5) * 0.8,
|
||||
(math_random() - 0.5) * 0.8,
|
||||
(math_random() - 0.5) * 0.8
|
||||
)
|
||||
local spark_pos = vector.add(pos, pos_addend)
|
||||
local spark = minetest.add_entity(spark_pos, "mcl_core:lava_spark")
|
||||
if not spark then return end
|
||||
|
||||
local velocity = vector.new(
|
||||
(math_random() - 0.5) * 3,
|
||||
(math_random() + 2) * 2,
|
||||
(math_random() - 0.5) * 3
|
||||
)
|
||||
spark:set_velocity(velocity)
|
||||
|
||||
spark:set_acceleration(vector.new(0, -9, 0))
|
||||
|
||||
-- Set a random size
|
||||
local size = 0.2 + math_random() * 0.2
|
||||
local props = spark:get_properties()
|
||||
if not props then return end
|
||||
props.visual_size = vector.new(size, size, size)
|
||||
spark:set_properties(props)
|
||||
|
||||
local luaentity = spark:get_luaentity()
|
||||
if not luaentity then return end
|
||||
luaentity._life_timer = 0.4 + math_random()
|
||||
end
|
||||
|
||||
if lava_spark_limit > 0 then
|
||||
mcl_core.lava_spark_set_chance()
|
||||
|
||||
|
@ -87,57 +134,20 @@ if lava_spark_limit > 0 then
|
|||
interval = LAVA_SPARK_ABM_INTERVAL,
|
||||
chance = 18,
|
||||
action = function(pos, node)
|
||||
local above = minetest.get_node(vector.new(pos.x, pos.y + 1, pos.z))
|
||||
local above = minetest_get_node(vector.new(pos.x, pos.y + 1, pos.z))
|
||||
if above.name ~= "air" then return end
|
||||
|
||||
|
||||
lava_spark_abm_census = lava_spark_abm_census + 1
|
||||
|
||||
|
||||
if lava_spark_census >= lava_spark_limit then return end
|
||||
if math.random() > lava_spark_chance then return end
|
||||
|
||||
if math_random() > lava_spark_chance then return end
|
||||
|
||||
lava_spark_census = lava_spark_census + 1
|
||||
minetest.after(math.random() * LAVA_SPARK_ABM_INTERVAL, mcl_core.lava_spark_add, pos)
|
||||
minetest_after(math_random() * LAVA_SPARK_ABM_INTERVAL, lava_spark_add, pos)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
function mcl_core.lava_spark_add(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if minetest.get_node_group(node.name, "lava") == 0 then return end
|
||||
|
||||
local above = minetest.get_node(vector.new(pos.x, pos.y + 1, pos.z))
|
||||
if above.name ~= "air" then return end
|
||||
|
||||
local pos_addend = vector.new(
|
||||
(math.random() - 0.5) * 0.8,
|
||||
(math.random() - 0.5) * 0.8,
|
||||
(math.random() - 0.5) * 0.8
|
||||
)
|
||||
local spark_pos = vector.add(pos, pos_addend)
|
||||
local spark = minetest.add_entity(spark_pos, "mcl_core:lava_spark")
|
||||
if not spark then return end
|
||||
|
||||
local velocity = vector.new(
|
||||
(math.random() - 0.5) * 3,
|
||||
(math.random() + 2) * 2,
|
||||
(math.random() - 0.5) * 3
|
||||
)
|
||||
spark:set_velocity(velocity)
|
||||
|
||||
spark:set_acceleration(vector.new(0, -9, 0))
|
||||
|
||||
-- Set a random size
|
||||
local size = 0.2 + math.random() * 0.2
|
||||
local props = spark:get_properties()
|
||||
if not props then return end
|
||||
props.visual_size = vector.new(size, size, size)
|
||||
spark:set_properties(props)
|
||||
|
||||
local luaentity = spark:get_luaentity()
|
||||
if not luaentity then return end
|
||||
luaentity._life_timer = 0.4 + math.random()
|
||||
end
|
||||
|
||||
minetest.register_entity("mcl_core:lava_spark", {
|
||||
physical = true,
|
||||
visual = "sprite",
|
||||
|
@ -159,7 +169,7 @@ minetest.register_entity("mcl_core:lava_spark", {
|
|||
|
||||
self._smoke_timer = self._smoke_timer - dtime
|
||||
if self._smoke_timer > 0 then return end
|
||||
self._smoke_timer = 0.2 + math.random() * 0.3
|
||||
self._smoke_timer = 0.2 + math_random() * 0.3
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
|
@ -185,44 +195,23 @@ minetest.register_entity("mcl_core:lava_spark", {
|
|||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- Papyrus and cactus growing
|
||||
--
|
||||
|
||||
-- Functions
|
||||
function mcl_core.grow_cactus(pos, node)
|
||||
pos.y = pos.y-1
|
||||
local name = minetest.get_node(pos).name
|
||||
if minetest.get_item_group(name, "sand") ~= 0 then
|
||||
pos.y = pos.y+1
|
||||
local height = 0
|
||||
while minetest.get_node(pos).name == "mcl_core:cactus" and height < 4 do
|
||||
height = height+1
|
||||
pos.y = pos.y+1
|
||||
end
|
||||
if height < 3 then
|
||||
if minetest.get_node(pos).name == "air" then
|
||||
minetest.set_node(pos, {name="mcl_core:cactus"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_core.grow_reeds(pos, node)
|
||||
pos.y = pos.y-1
|
||||
local name = minetest.get_node(pos).name
|
||||
if minetest.get_item_group(name, "soil_sugarcane") ~= 0 then
|
||||
local name = minetest_get_node(pos).name
|
||||
if minetest_get_item_group(name, "soil_sugarcane") ~= 0 then
|
||||
if minetest.find_node_near(pos, 1, {"group:water"}) == nil and minetest.find_node_near(pos, 1, {"group:frosted_ice"}) == nil then
|
||||
return
|
||||
end
|
||||
pos.y = pos.y+1
|
||||
local height = 0
|
||||
while minetest.get_node(pos).name == "mcl_core:reeds" and height < 3 do
|
||||
while minetest_get_node(pos).name == "mcl_core:reeds" and height < 3 do
|
||||
height = height+1
|
||||
pos.y = pos.y+1
|
||||
end
|
||||
if height < 3 then
|
||||
if minetest.get_node(pos).name == "air" then
|
||||
if minetest_get_node(pos).name == "air" then
|
||||
minetest.set_node(pos, {name="mcl_core:reeds"})
|
||||
end
|
||||
end
|
||||
|
@ -231,18 +220,17 @@ end
|
|||
|
||||
-- ABMs
|
||||
|
||||
|
||||
local function drop_attached_node(p)
|
||||
local nn = minetest.get_node(p).name
|
||||
local nn = minetest_get_node(p).name
|
||||
if nn == "air" or nn == "ignore" then
|
||||
return
|
||||
end
|
||||
minetest.remove_node(p)
|
||||
for _, item in pairs(minetest.get_node_drops(nn, "")) do
|
||||
for _, item in pairs(minetest_get_node_drops(nn, "")) do
|
||||
local pos = {
|
||||
x = p.x + math.random()/2 - 0.25,
|
||||
y = p.y + math.random()/2 - 0.25,
|
||||
z = p.z + math.random()/2 - 0.25,
|
||||
x = p.x + math_random()/2 - 0.25,
|
||||
y = p.y + math_random()/2 - 0.25,
|
||||
z = p.z + math_random()/2 - 0.25,
|
||||
}
|
||||
if item ~= "" then
|
||||
minetest.add_item(pos, item)
|
||||
|
@ -254,11 +242,11 @@ end
|
|||
local function liquid_flow_action(pos, group, action)
|
||||
local function check_detach(pos, xp, yp, zp)
|
||||
local p = {x=pos.x+xp, y=pos.y+yp, z=pos.z+zp}
|
||||
local n = minetest.get_node_or_nil(p)
|
||||
local n = minetest_get_node_or_nil(p)
|
||||
if not n then
|
||||
return false
|
||||
end
|
||||
local d = minetest.registered_nodes[n.name]
|
||||
local d = minetest_registered_nodes[n.name]
|
||||
if not d then
|
||||
return false
|
||||
end
|
||||
|
@ -267,7 +255,7 @@ local function liquid_flow_action(pos, group, action)
|
|||
* 2a: If target node is below liquid, always succeed
|
||||
* 2b: If target node is horizontal to liquid: succeed if source, otherwise check param2 for horizontal flow direction ]]
|
||||
local range = d.liquid_range or 8
|
||||
if (minetest.get_item_group(n.name, group) ~= 0) and
|
||||
if (minetest_get_item_group(n.name, group) ~= 0) and
|
||||
((yp > 0) or
|
||||
(yp == 0 and ((d.liquidtype == "source") or (n.param2 > (8-range) and n.param2 < 9)))) then
|
||||
action(pos)
|
||||
|
@ -316,17 +304,23 @@ minetest.register_abm({
|
|||
end,
|
||||
})
|
||||
|
||||
-- Cactus mechanisms
|
||||
minetest.register_abm({
|
||||
label = "Cactus growth",
|
||||
nodenames = {"mcl_core:cactus"},
|
||||
neighbors = {"group:sand"},
|
||||
interval = 25,
|
||||
chance = 10,
|
||||
action = function(pos)
|
||||
mcl_core.grow_cactus(pos)
|
||||
end,
|
||||
})
|
||||
local function cactus_grow(pos, node)
|
||||
local pos = pos
|
||||
local y = pos.y
|
||||
pos.y = y - 1
|
||||
local name = minetest_get_node(pos).name
|
||||
if minetest_get_item_group(name, "sand") == 0 then return end
|
||||
|
||||
for i = 1, 2 do
|
||||
pos.y = y + i
|
||||
name = minetest_get_node(pos).name
|
||||
if name == "air" then
|
||||
minetest.set_node(pos, {name = "mcl_core:cactus"})
|
||||
return
|
||||
end
|
||||
if name ~= "mcl_core:cactus" then return end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Cactus mechanisms",
|
||||
|
@ -334,39 +328,34 @@ minetest.register_abm({
|
|||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
for _, object in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do
|
||||
local pos = pos
|
||||
local x, y, z = pos.x, pos.y, pos.z
|
||||
|
||||
if minetest_registered_nodes[minetest_get_node({x = x + 1, y = y, z = z}).name].walkable
|
||||
or minetest_registered_nodes[minetest_get_node({x = x - 1, y = y, z = z}).name].walkable
|
||||
or minetest_registered_nodes[minetest_get_node({x = x, y = y, z = z + 1}).name].walkable
|
||||
or minetest_registered_nodes[minetest_get_node({x = x, y = y, z = z - 1}).name].walkable
|
||||
then
|
||||
while minetest_get_node(pos).name == "mcl_core:cactus" do
|
||||
minetest.remove_node(pos)
|
||||
minetest.add_item(vector.offset(pos, math_random(-0.5, 0.5), 0, math_random(-0.5, 0.5)), "mcl_core:cactus")
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
for _, object in pairs(minetest_get_objects_inside_radius(pos, 0.9)) do
|
||||
local entity = object:get_luaentity()
|
||||
if entity then
|
||||
local entity_name = entity.name
|
||||
if entity_name == "__builtin:item" then
|
||||
object:remove()
|
||||
elseif entity_name == "mcl_minecarts:minecart" then
|
||||
local pos = object:get_pos()
|
||||
local driver = entity._driver
|
||||
if driver then
|
||||
mcl_player.player_attached[driver] = nil
|
||||
local player = minetest.get_player_by_name(driver)
|
||||
player:set_detach()
|
||||
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
mcl_player.player_set_animation(player, "stand" , 30)
|
||||
end
|
||||
minetest.add_item(pos, "mcl_minecarts:minecart")
|
||||
object:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
local posses = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }
|
||||
for _, p in pairs(posses) do
|
||||
if minetest.registered_nodes[minetest.get_node(vector.new(pos.x + p[1], pos.y, pos.z + p[2])).name].walkable then
|
||||
local posy = pos.y
|
||||
while minetest.get_node(vector.new(pos.x, posy, pos.z)).name == "mcl_core:cactus" do
|
||||
local pos = vector.new(pos.x, posy, pos.z)
|
||||
minetest.remove_node(pos)
|
||||
minetest.add_item(vector.offset(pos, math.random(-0.5, 0.5), 0, math.random(-0.5, 0.5)), "mcl_core:cactus")
|
||||
posy = posy + 1
|
||||
end
|
||||
break
|
||||
end
|
||||
|
||||
for i = 1, mcl_time_get_number_of_times_at_pos(pos, 25, 10) do
|
||||
cactus_grow(pos)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -393,7 +382,7 @@ minetest.register_on_dignode(function(pos, node)
|
|||
local i=1
|
||||
while timber_nodenames[i]~=nil do
|
||||
local np={x=pos.x, y=pos.y+1, z=pos.z}
|
||||
while minetest.get_node(np).name==timber_nodenames[i] do
|
||||
while minetest_get_node(np).name==timber_nodenames[i] do
|
||||
minetest.remove_node(np)
|
||||
minetest.add_item(np, timber_nodenames[i])
|
||||
np={x=np.x, y=np.y+1, z=np.z}
|
||||
|
@ -403,7 +392,7 @@ minetest.register_on_dignode(function(pos, node)
|
|||
end)
|
||||
|
||||
local function air_leaf(leaftype)
|
||||
if math.random(0, 50) == 3 then
|
||||
if math_random(0, 50) == 3 then
|
||||
return {name = "air"}
|
||||
else
|
||||
return {name = leaftype}
|
||||
|
@ -417,7 +406,7 @@ local function node_stops_growth(node)
|
|||
return false
|
||||
end
|
||||
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local def = minetest_registered_nodes[node.name]
|
||||
if not def then
|
||||
return true
|
||||
end
|
||||
|
@ -450,7 +439,7 @@ local function check_growth_width(pos, width, height)
|
|||
pos.x + x,
|
||||
pos.y + y,
|
||||
pos.z + z)
|
||||
if node_stops_growth(minetest.get_node(np)) then
|
||||
if node_stops_growth(minetest_get_node(np)) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -502,10 +491,10 @@ end
|
|||
-- oak tree.
|
||||
function mcl_core.generate_tree(pos, tree_type, options)
|
||||
pos.y = pos.y-1
|
||||
--local nodename = minetest.get_node(pos).name
|
||||
--local nodename = minetest_get_node(pos).name
|
||||
|
||||
pos.y = pos.y+1
|
||||
if not minetest.get_node_light(pos) then
|
||||
if not minetest_get_node_light(pos) then
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -558,7 +547,7 @@ function mcl_core.generate_v6_oak_tree(pos)
|
|||
local node
|
||||
for dy=1,4 do
|
||||
pos.y = pos.y+dy
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
if minetest_get_node(pos).name ~= "air" then
|
||||
return
|
||||
end
|
||||
pos.y = pos.y-dy
|
||||
|
@ -566,7 +555,7 @@ function mcl_core.generate_v6_oak_tree(pos)
|
|||
node = {name = trunk}
|
||||
for dy=0,4 do
|
||||
pos.y = pos.y+dy
|
||||
if minetest.get_node(pos).name == "air" then
|
||||
if minetest_get_node(pos).name == "air" then
|
||||
minetest.add_node(pos, node)
|
||||
end
|
||||
pos.y = pos.y-dy
|
||||
|
@ -575,7 +564,7 @@ function mcl_core.generate_v6_oak_tree(pos)
|
|||
node = {name = leaves}
|
||||
pos.y = pos.y+3
|
||||
--[[local rarity = 0
|
||||
if math.random(0, 10) == 3 then
|
||||
if math_random(0, 10) == 3 then
|
||||
rarity = 1
|
||||
end]]
|
||||
for dx=-2,2 do
|
||||
|
@ -586,23 +575,23 @@ function mcl_core.generate_v6_oak_tree(pos)
|
|||
pos.z = pos.z+dz
|
||||
|
||||
if dx == 0 and dz == 0 and dy==3 then
|
||||
if minetest.get_node(pos).name == "air" and math.random(1, 5) <= 4 then
|
||||
if minetest_get_node(pos).name == "air" and math_random(1, 5) <= 4 then
|
||||
minetest.add_node(pos, node)
|
||||
minetest.add_node(pos, air_leaf(leaves))
|
||||
end
|
||||
elseif dx == 0 and dz == 0 and dy==4 then
|
||||
if minetest.get_node(pos).name == "air" and math.random(1, 5) <= 4 then
|
||||
if minetest_get_node(pos).name == "air" and math_random(1, 5) <= 4 then
|
||||
minetest.add_node(pos, node)
|
||||
minetest.add_node(pos, air_leaf(leaves))
|
||||
end
|
||||
elseif math.abs(dx) ~= 2 and math.abs(dz) ~= 2 then
|
||||
if minetest.get_node(pos).name == "air" then
|
||||
if minetest_get_node(pos).name == "air" then
|
||||
minetest.add_node(pos, node)
|
||||
minetest.add_node(pos, air_leaf(leaves))
|
||||
end
|
||||
else
|
||||
if math.abs(dx) ~= 2 or math.abs(dz) ~= 2 then
|
||||
if minetest.get_node(pos).name == "air" and math.random(1, 5) <= 4 then
|
||||
if minetest_get_node(pos).name == "air" and math_random(1, 5) <= 4 then
|
||||
minetest.add_node(pos, node)
|
||||
minetest.add_node(pos, air_leaf(leaves))
|
||||
end
|
||||
|
@ -620,14 +609,14 @@ end
|
|||
function mcl_core.generate_balloon_oak_tree(pos)
|
||||
local path
|
||||
local offset
|
||||
local s = math.random(1, 12)
|
||||
local s = math_random(1, 12)
|
||||
if s == 1 then
|
||||
-- Small balloon oak
|
||||
path = modpath .. "/schematics/mcl_core_oak_balloon.mts"
|
||||
offset = { x = -2, y = -1, z = -2 }
|
||||
else
|
||||
-- Large balloon oak
|
||||
local t = math.random(1, 4)
|
||||
local t = math_random(1, 4)
|
||||
path = modpath .. "/schematics/mcl_core_oak_large_"..t..".mts"
|
||||
if t == 1 or t == 3 then
|
||||
offset = { x = -3, y = -1, z = -3 }
|
||||
|
@ -666,7 +655,7 @@ end
|
|||
|
||||
function mcl_core.generate_v6_spruce_tree(pos)
|
||||
local x, y, z = pos.x, pos.y, pos.z
|
||||
local maxy = y + math.random(9, 13) -- Trunk top
|
||||
local maxy = y + math_random(9, 13) -- Trunk top
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_ignore = minetest.get_content_id("ignore")
|
||||
|
@ -689,7 +678,7 @@ function mcl_core.generate_v6_spruce_tree(pos)
|
|||
local vi = a:index(x - dev, yy, zz)
|
||||
local via = a:index(x - dev, yy + 1, zz)
|
||||
for xx = x - dev, x + dev do
|
||||
if math.random() < 0.95 - dev * 0.05 then
|
||||
if math_random() < 0.95 - dev * 0.05 then
|
||||
add_spruce_leaves(data, vi, c_air, c_ignore, c_snow,
|
||||
c_spruce_leaves)
|
||||
end
|
||||
|
@ -709,9 +698,9 @@ function mcl_core.generate_v6_spruce_tree(pos)
|
|||
-- Lower branches layer
|
||||
local my = 0
|
||||
for i = 1, 20 do -- Random 2x2 squares of leaves
|
||||
local xi = x + math.random(-3, 2)
|
||||
local yy = maxy + math.random(-6, -5)
|
||||
local zi = z + math.random(-3, 2)
|
||||
local xi = x + math_random(-3, 2)
|
||||
local yy = maxy + math_random(-6, -5)
|
||||
local zi = z + math_random(-3, 2)
|
||||
if yy > my then
|
||||
my = yy
|
||||
end
|
||||
|
@ -733,7 +722,7 @@ function mcl_core.generate_v6_spruce_tree(pos)
|
|||
local vi = a:index(x - dev, yy, zz)
|
||||
local via = a:index(x - dev, yy + 1, zz)
|
||||
for xx = x - dev, x + dev do
|
||||
if math.random() < 0.95 - dev * 0.05 then
|
||||
if math_random() < 0.95 - dev * 0.05 then
|
||||
add_spruce_leaves(data, vi, c_air, c_ignore, c_snow,
|
||||
c_spruce_leaves)
|
||||
end
|
||||
|
@ -761,14 +750,14 @@ function mcl_core.generate_v6_spruce_tree(pos)
|
|||
end
|
||||
|
||||
function mcl_core.generate_spruce_tree(pos)
|
||||
local r = math.random(1, 3)
|
||||
local r = math_random(1, 3)
|
||||
local path = modpath .. "/schematics/mcl_core_spruce_"..r..".mts"
|
||||
minetest.place_schematic({ x = pos.x - 3, y = pos.y - 1, z = pos.z - 3 }, path, "0", nil, false)
|
||||
end
|
||||
|
||||
function mcl_core.generate_huge_spruce_tree(pos)
|
||||
local r1 = math.random(1, 2)
|
||||
local r2 = math.random(1, 4)
|
||||
local r1 = math_random(1, 2)
|
||||
local r2 = math_random(1, 4)
|
||||
local path
|
||||
local offset = { x = -4, y = -1, z = -5 }
|
||||
if r1 <= 2 then
|
||||
|
@ -788,7 +777,7 @@ end
|
|||
|
||||
-- Acacia tree (multiple variants)
|
||||
function mcl_core.generate_acacia_tree(pos)
|
||||
local r = math.random(1, 7)
|
||||
local r = math_random(1, 7)
|
||||
local offset = vector.new()
|
||||
if r == 2 or r == 3 then
|
||||
offset = { x = -4, y = -1, z = -4 }
|
||||
|
@ -840,9 +829,9 @@ local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid,
|
|||
|
||||
-- Randomly add leaves in 2x2x2 clusters.
|
||||
for i = 1, iters do
|
||||
local clust_x = x + math.random(-size, size - 1)
|
||||
local clust_y = y + height + math.random(-size, 0)
|
||||
local clust_z = z + math.random(-size, size - 1)
|
||||
local clust_x = x + math_random(-size, size - 1)
|
||||
local clust_y = y + height + math_random(-size, 0)
|
||||
local clust_z = z + math_random(-size, size - 1)
|
||||
|
||||
for xi = 0, 1 do
|
||||
for yi = 0, 1 do
|
||||
|
@ -866,7 +855,7 @@ function mcl_core.generate_v6_jungle_tree(pos)
|
|||
--]]
|
||||
|
||||
local x, y, z = pos.x, pos.y, pos.z
|
||||
local height = math.random(8, 12)
|
||||
local height = math_random(8, 12)
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_ignore = minetest.get_content_id("ignore")
|
||||
local c_jungletree = minetest.get_content_id("mcl_core:jungletree")
|
||||
|
@ -887,7 +876,7 @@ function mcl_core.generate_v6_jungle_tree(pos)
|
|||
local vi_1 = a:index(x - 1, y - 1, z + z_dist)
|
||||
local vi_2 = a:index(x - 1, y, z + z_dist)
|
||||
for x_dist = -1, 1 do
|
||||
if math.random(1, 3) >= 2 then
|
||||
if math_random(1, 3) >= 2 then
|
||||
if data[vi_1] == c_air or data[vi_1] == c_ignore then
|
||||
data[vi_1] = c_jungletree
|
||||
elseif data[vi_2] == c_air or data[vi_2] == c_ignore then
|
||||
|
@ -912,7 +901,7 @@ end
|
|||
-- With pos being the lower X and the higher Z value of the trunk.
|
||||
function mcl_core.generate_huge_jungle_tree(pos)
|
||||
-- 2 variants
|
||||
local r = math.random(1, 2)
|
||||
local r = math_random(1, 2)
|
||||
local path = modpath.."/schematics/mcl_core_jungle_tree_huge_"..r..".mts"
|
||||
minetest.place_schematic({x = pos.x - 6, y = pos.y - 1, z = pos.z - 7}, path, "random", nil, false)
|
||||
end
|
||||
|
@ -954,12 +943,12 @@ minetest.register_abm({
|
|||
return
|
||||
end
|
||||
local above = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local abovenode = minetest.get_node(above)
|
||||
if minetest.get_item_group(abovenode.name, "liquid") ~= 0 or minetest.get_item_group(abovenode.name, "opaque") == 1 then
|
||||
local abovenode = minetest_get_node(above)
|
||||
if minetest_get_item_group(abovenode.name, "liquid") ~= 0 or minetest_get_item_group(abovenode.name, "opaque") == 1 then
|
||||
-- Never grow directly below liquids or opaque blocks
|
||||
return
|
||||
end
|
||||
local light_self = minetest.get_node_light(above)
|
||||
local light_self = minetest_get_node_light(above)
|
||||
if not light_self then return end
|
||||
--[[ Try to find a spreading dirt-type block (e.g. grass block or mycelium)
|
||||
within a 3×5×3 area, with the source block being on the 2nd-topmost layer. ]]
|
||||
|
@ -974,20 +963,20 @@ minetest.register_abm({
|
|||
|
||||
-- Found it! Now check light levels!
|
||||
local source_above = {x=p2.x, y=p2.y+1, z=p2.z}
|
||||
local light_source = minetest.get_node_light(source_above)
|
||||
local light_source = minetest_get_node_light(source_above)
|
||||
if not light_source then return end
|
||||
|
||||
if light_self >= 4 and light_source >= 9 then
|
||||
-- All checks passed! Let's spread the grass/mycelium!
|
||||
local n2 = minetest.get_node(p2)
|
||||
if minetest.get_item_group(n2.name, "grass_block") ~= 0 then
|
||||
local n2 = minetest_get_node(p2)
|
||||
if minetest_get_item_group(n2.name, "grass_block") ~= 0 then
|
||||
n2 = mcl_core.get_grass_block_type(pos)
|
||||
end
|
||||
minetest.set_node(pos, {name=n2.name})
|
||||
|
||||
-- If this was mycelium, uproot plant above
|
||||
if n2.name == "mcl_core:mycelium" then
|
||||
local tad = minetest.registered_nodes[minetest.get_node(above).name]
|
||||
local tad = minetest_registered_nodes[minetest_get_node(above).name]
|
||||
if tad.groups and tad.groups.non_mycelium_plant then
|
||||
minetest.dig_node(above)
|
||||
end
|
||||
|
@ -1005,9 +994,9 @@ minetest.register_abm({
|
|||
catch_up = false,
|
||||
action = function(pos, node)
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local name = minetest.get_node(above).name
|
||||
local name = minetest_get_node(above).name
|
||||
-- Kill grass/mycelium when below opaque block or liquid
|
||||
if name ~= "ignore" and (minetest.get_item_group(name, "opaque") == 1 or minetest.get_item_group(name, "liquid") ~= 0) then
|
||||
if name ~= "ignore" and (minetest_get_item_group(name, "opaque") == 1 or minetest_get_item_group(name, "liquid") ~= 0) then
|
||||
minetest.set_node(pos, {name = "mcl_core:dirt"})
|
||||
end
|
||||
end
|
||||
|
@ -1015,11 +1004,11 @@ minetest.register_abm({
|
|||
|
||||
-- Turn Grass Path and similar nodes to Dirt if a solid node is placed above it
|
||||
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
||||
if minetest.get_item_group(newnode.name, "solid") ~= 0 or
|
||||
minetest.get_item_group(newnode.name, "dirtifier") ~= 0 then
|
||||
if minetest_get_item_group(newnode.name, "solid") ~= 0 or
|
||||
minetest_get_item_group(newnode.name, "dirtifier") ~= 0 then
|
||||
local below = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local belownode = minetest.get_node(below)
|
||||
if minetest.get_item_group(belownode.name, "dirtifies_below_solid") == 1 then
|
||||
local belownode = minetest_get_node(below)
|
||||
if minetest_get_item_group(belownode.name, "dirtifies_below_solid") == 1 then
|
||||
minetest.set_node(below, {name="mcl_core:dirt"})
|
||||
end
|
||||
end
|
||||
|
@ -1033,8 +1022,8 @@ minetest.register_abm({
|
|||
chance = 50,
|
||||
action = function(pos, node)
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local name = minetest.get_node(above).name
|
||||
local nodedef = minetest.registered_nodes[name]
|
||||
local name = minetest_get_node(above).name
|
||||
local nodedef = minetest_registered_nodes[name]
|
||||
if name ~= "ignore" and nodedef and (nodedef.groups and nodedef.groups.solid) then
|
||||
minetest.set_node(pos, {name = "mcl_core:dirt"})
|
||||
end
|
||||
|
@ -1083,7 +1072,7 @@ local function sapling_grow_action(tree_id, soil_needed, one_by_one, two_by_two,
|
|||
local meta = minetest.get_meta(pos)
|
||||
if meta:get("grown") then return end
|
||||
-- Checks if the sapling at pos has enough light and the correct soil
|
||||
local light = minetest.get_node_light(pos)
|
||||
local light = minetest_get_node_light(pos)
|
||||
if not light then return end
|
||||
local low_light = (light < treelight)
|
||||
|
||||
|
@ -1101,13 +1090,13 @@ local function sapling_grow_action(tree_id, soil_needed, one_by_one, two_by_two,
|
|||
|
||||
if low_light then
|
||||
if delta < 1.2 then return end
|
||||
if minetest.get_node_light(pos, 0.5) < treelight then return end
|
||||
if minetest_get_node_light(pos, 0.5) < treelight then return end
|
||||
end
|
||||
|
||||
-- TODO: delta is [days] missed in inactive area. Currently we just add it to stage, which is far from a perfect calculation...
|
||||
|
||||
local soilnode = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
|
||||
local soiltype = minetest.get_item_group(soilnode.name, "soil_sapling")
|
||||
local soilnode = minetest_get_node({x=pos.x, y=pos.y-1, z=pos.z})
|
||||
local soiltype = minetest_get_item_group(soilnode.name, "soil_sapling")
|
||||
if soiltype < soil_needed then return end
|
||||
|
||||
-- Increase and check growth stage
|
||||
|
@ -1121,7 +1110,7 @@ local function sapling_grow_action(tree_id, soil_needed, one_by_one, two_by_two,
|
|||
if two_by_two then
|
||||
-- Check 8 surrounding saplings and try to find a 2×2 pattern
|
||||
local function is_sapling(pos, sapling)
|
||||
return minetest.get_node(pos).name == sapling
|
||||
return minetest_get_node(pos).name == sapling
|
||||
end
|
||||
local p2 = {x=pos.x+1, y=pos.y, z=pos.z}
|
||||
local p3 = {x=pos.x, y=pos.y, z=pos.z-1}
|
||||
|
@ -1173,7 +1162,7 @@ local function sapling_grow_action(tree_id, soil_needed, one_by_one, two_by_two,
|
|||
end
|
||||
if one_by_one and tree_id == OAK_TREE_ID then
|
||||
-- There is a chance that this tree wants to grow as a balloon oak
|
||||
if math.random(1, 12) == 1 then
|
||||
if math_random(1, 12) == 1 then
|
||||
-- Check if there is room for that
|
||||
if check_tree_growth(pos, tree_id, { balloon = true }) then
|
||||
minetest.set_node(pos, {name="air"})
|
||||
|
@ -1186,7 +1175,7 @@ local function sapling_grow_action(tree_id, soil_needed, one_by_one, two_by_two,
|
|||
if one_by_one and check_tree_growth(pos, tree_id) then
|
||||
-- Single sapling
|
||||
minetest.set_node(pos, {name="air"})
|
||||
--local r = math.random(1, 12)
|
||||
--local r = math_random(1, 12)
|
||||
mcl_core.generate_tree(pos, tree_id)
|
||||
return
|
||||
end
|
||||
|
@ -1205,7 +1194,7 @@ local grow_birch = sapling_grow_action(BIRCH_TREE_ID, 1, true, false)
|
|||
|
||||
-- Attempts to grow the sapling at the specified position
|
||||
-- pos: Position
|
||||
-- node: Node table of the node at this position, from minetest.get_node
|
||||
-- node: Node table of the node at this position, from minetest_get_node
|
||||
-- Returns true on success and false on failure
|
||||
function mcl_core.grow_sapling(pos, node)
|
||||
local grow
|
||||
|
@ -1337,7 +1326,7 @@ minetest.register_lbm({
|
|||
|
||||
local function leafdecay_particles(pos, node)
|
||||
minetest.add_particlespawner({
|
||||
amount = math.random(10, 20),
|
||||
amount = math_random(10, 20),
|
||||
time = 0.1,
|
||||
minpos = vector.add(pos, {x=-0.4, y=-0.4, z=-0.4}),
|
||||
maxpos = vector.add(pos, {x=0.4, y=0.4, z=0.4}),
|
||||
|
@ -1375,7 +1364,7 @@ local function vinedecay_particles(pos, node)
|
|||
end
|
||||
|
||||
minetest.add_particlespawner({
|
||||
amount = math.random(8, 16),
|
||||
amount = math_random(8, 16),
|
||||
time = 0.1,
|
||||
minpos = vector.add(pos, relpos1),
|
||||
maxpos = vector.add(pos, relpos2),
|
||||
|
@ -1413,8 +1402,8 @@ minetest.register_abm({
|
|||
|
||||
-- Add vines below pos (if empty)
|
||||
local function spread_down(origin, target, dir, node)
|
||||
if math.random(1, 2) == 1 then
|
||||
if minetest.get_node(target).name == "air" then
|
||||
if math_random(1, 2) == 1 then
|
||||
if minetest_get_node(target).name == "air" then
|
||||
minetest.add_node(target, {name = "mcl_core:vine", param2 = node.param2})
|
||||
end
|
||||
end
|
||||
|
@ -1425,11 +1414,11 @@ minetest.register_abm({
|
|||
local vines_in_area = minetest.find_nodes_in_area({x=origin.x-4, y=origin.y-1, z=origin.z-4}, {x=origin.x+4, y=origin.y+1, z=origin.z+4}, "mcl_core:vine")
|
||||
-- Less then 4 vines blocks around the ticked vines block (remember the ticked block is counted by above function as well)
|
||||
if #vines_in_area < 5 then
|
||||
if math.random(1, 2) == 1 then
|
||||
if minetest.get_node(target).name == "air" then
|
||||
if math_random(1, 2) == 1 then
|
||||
if minetest_get_node(target).name == "air" then
|
||||
local backup_dir = minetest.wallmounted_to_dir(node.param2)
|
||||
local backup = vector.subtract(target, backup_dir)
|
||||
local backupnodename = minetest.get_node(backup).name
|
||||
local backupnodename = minetest_get_node(backup).name
|
||||
|
||||
-- Check if the block above is supported
|
||||
if mcl_core.supports_vines(backupnodename) then
|
||||
|
@ -1447,10 +1436,10 @@ minetest.register_abm({
|
|||
-- Spread horizontally
|
||||
local backup_dir = minetest.wallmounted_to_dir(node.param2)
|
||||
if not vector.equals(backup_dir, dir) then
|
||||
local target_node = minetest.get_node(target)
|
||||
local target_node = minetest_get_node(target)
|
||||
if target_node.name == "air" then
|
||||
local backup = vector.add(target, backup_dir)
|
||||
local backupnodename = minetest.get_node(backup).name
|
||||
local backupnodename = minetest_get_node(backup).name
|
||||
if mcl_core.supports_vines(backupnodename) then
|
||||
minetest.add_node(target, {name = "mcl_core:vine", param2 = node.param2})
|
||||
end
|
||||
|
@ -1468,7 +1457,7 @@ minetest.register_abm({
|
|||
{ { x= 0, y= 0, z=-1 }, spread_horizontal },
|
||||
}
|
||||
|
||||
local d = math.random(1, #directions)
|
||||
local d = math_random(1, #directions)
|
||||
local dir = directions[d][1]
|
||||
local spread = directions[d][2]
|
||||
|
||||
|
@ -1478,7 +1467,7 @@ minetest.register_abm({
|
|||
|
||||
-- Returns true of the node supports vines
|
||||
function mcl_core.supports_vines(nodename)
|
||||
local def = minetest.registered_nodes[nodename]
|
||||
local def = minetest_registered_nodes[nodename]
|
||||
-- Rules: 1) walkable 2) full cube
|
||||
return def.walkable and
|
||||
(def.node_box == nil or def.node_box.type == "regular") and
|
||||
|
@ -1516,11 +1505,11 @@ minetest.register_abm({
|
|||
|
||||
action = function(p0, node, _, _)
|
||||
local do_preserve = false
|
||||
local d = minetest.registered_nodes[node.name].groups.leafdecay
|
||||
local d = minetest_registered_nodes[node.name].groups.leafdecay
|
||||
if not d or d == 0 then
|
||||
return
|
||||
end
|
||||
local n0 = minetest.get_node(p0)
|
||||
local n0 = minetest_get_node(p0)
|
||||
if n0.param2 ~= 0 then
|
||||
-- Prevent leafdecay for player-placed leaves.
|
||||
-- param2 is set to 1 after it was placed by the player
|
||||
|
@ -1531,8 +1520,8 @@ minetest.register_abm({
|
|||
p0_hash = minetest.hash_node_position(p0)
|
||||
local trunkp = mcl_core.leafdecay_trunk_cache[p0_hash]
|
||||
if trunkp then
|
||||
local n = minetest.get_node(trunkp)
|
||||
local reg = minetest.registered_nodes[n.name]
|
||||
local n = minetest_get_node(trunkp)
|
||||
local reg = minetest_registered_nodes[n.name]
|
||||
-- Assume ignore is a trunk, to make the thing work at the border of the active area
|
||||
if n.name == "ignore" or (reg and reg.groups.tree and reg.groups.tree ~= 0) then
|
||||
return
|
||||
|
@ -1557,12 +1546,12 @@ minetest.register_abm({
|
|||
end
|
||||
if not do_preserve then
|
||||
-- Drop stuff other than the node itself
|
||||
local itemstacks = minetest.get_node_drops(n0.name)
|
||||
local itemstacks = minetest_get_node_drops(n0.name)
|
||||
for _, itemname in pairs(itemstacks) do
|
||||
local p_drop = {
|
||||
x = p0.x - 0.5 + math.random(),
|
||||
y = p0.y - 0.5 + math.random(),
|
||||
z = p0.z - 0.5 + math.random(),
|
||||
x = p0.x - 0.5 + math_random(),
|
||||
y = p0.y - 0.5 + math_random(),
|
||||
z = p0.z - 0.5 + math_random(),
|
||||
}
|
||||
minetest.add_item(p_drop, itemname)
|
||||
end
|
||||
|
@ -1581,7 +1570,7 @@ minetest.register_abm({
|
|||
}
|
||||
for s=1, #surround do
|
||||
local spos = vector.add(p0, surround[s])
|
||||
local maybe_vine = minetest.get_node(spos)
|
||||
local maybe_vine = minetest_get_node(spos)
|
||||
--local surround_inverse = vector.multiply(surround[s], -1)
|
||||
if maybe_vine.name == "mcl_core:vine" and (not mcl_core.check_vines_supported(spos, maybe_vine)) then
|
||||
minetest.remove_node(spos)
|
||||
|
@ -1622,7 +1611,7 @@ minetest.register_abm({
|
|||
interval = 16,
|
||||
chance = 8,
|
||||
action = function(pos, node)
|
||||
if minetest.get_node_light(pos, 0) >= 12 then
|
||||
if minetest_get_node_light(pos, 0) >= 12 then
|
||||
if node.name == "mcl_core:ice" then
|
||||
mcl_core.melt_ice(pos)
|
||||
else
|
||||
|
@ -1640,7 +1629,7 @@ function mcl_core.check_vines_supported(pos, node)
|
|||
local supported = false
|
||||
local dir = minetest.wallmounted_to_dir(node.param2)
|
||||
local pos1 = vector.add(pos, dir)
|
||||
local node_neighbor = minetest.get_node(pos1)
|
||||
local node_neighbor = minetest_get_node(pos1)
|
||||
-- Check if vines are attached to a solid block.
|
||||
-- If ignore, we assume its solid.
|
||||
if node_neighbor.name == "ignore" or mcl_core.supports_vines(node_neighbor.name) then
|
||||
|
@ -1649,7 +1638,7 @@ function mcl_core.check_vines_supported(pos, node)
|
|||
-- Vines are not attached, now we check if the vines are “hanging” below another vines block
|
||||
-- of equal orientation.
|
||||
local pos2 = vector.add(pos, {x=0, y=1, z=0})
|
||||
local node2 = minetest.get_node(pos2)
|
||||
local node2 = minetest_get_node(pos2)
|
||||
-- Again, ignore means we assume its supported
|
||||
if node2.name == "ignore" or (node2.name == "mcl_core:vine" and node2.param2 == node.param2) then
|
||||
supported = true
|
||||
|
@ -1662,7 +1651,7 @@ end
|
|||
function mcl_core.melt_ice(pos)
|
||||
-- Create a water source if ice is destroyed and there was something below it
|
||||
local below = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local belownode = minetest.get_node(below)
|
||||
local belownode = minetest_get_node(below)
|
||||
local dim = mcl_worlds.pos_to_dimension(below)
|
||||
if dim ~= "nether" and belownode.name ~= "air" and belownode.name ~= "ignore" and belownode.name ~= "mcl_core:void" then
|
||||
minetest.set_node(pos, {name="mcl_core:water_source"})
|
||||
|
@ -1697,7 +1686,7 @@ end
|
|||
-- The snowable nodes also MUST have _mcl_snowed defined to contain the name
|
||||
-- of the snowed node.
|
||||
function mcl_core.register_snowed_node(itemstring_snowed, itemstring_clear, tiles, sounds, clear_colorization, desc)
|
||||
local def = table.copy(minetest.registered_nodes[itemstring_clear])
|
||||
local def = table.copy(minetest_registered_nodes[itemstring_clear])
|
||||
local create_doc_alias
|
||||
if def.description then
|
||||
create_doc_alias = true
|
||||
|
@ -1760,7 +1749,7 @@ end
|
|||
-- This function assumes there is no snow cover node above. This function
|
||||
-- MUST NOT be called if there is a snow cover node above pos.
|
||||
function mcl_core.clear_snow_dirt(pos, node)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local def = minetest_registered_nodes[node.name]
|
||||
if def._mcl_snowless then
|
||||
minetest.swap_node(pos, {name = def._mcl_snowless, param2=node.param2})
|
||||
end
|
||||
|
@ -1773,15 +1762,15 @@ end
|
|||
-- Makes constructed snowable node snowed if placed below a snow cover node.
|
||||
function mcl_core.on_snowable_construct(pos)
|
||||
-- Myself
|
||||
local node = minetest.get_node(pos)
|
||||
local node = minetest_get_node(pos)
|
||||
|
||||
-- Above
|
||||
local apos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local anode = minetest.get_node(apos)
|
||||
local anode = minetest_get_node(apos)
|
||||
|
||||
-- Make snowed if needed
|
||||
if minetest.get_item_group(anode.name, "snow_cover") == 1 then
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if minetest_get_item_group(anode.name, "snow_cover") == 1 then
|
||||
local def = minetest_registered_nodes[node.name]
|
||||
if def._mcl_snowed then
|
||||
minetest.swap_node(pos, {name = def._mcl_snowed, param2=node.param2})
|
||||
end
|
||||
|
@ -1801,8 +1790,8 @@ end
|
|||
-- Makes snowable node below snowed.
|
||||
function mcl_core.on_snow_construct(pos)
|
||||
local npos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local node = minetest.get_node(npos)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local node = minetest_get_node(npos)
|
||||
local def = minetest_registered_nodes[node.name]
|
||||
if def._mcl_snowed then
|
||||
minetest.swap_node(npos, {name = def._mcl_snowed, param2=node.param2})
|
||||
end
|
||||
|
@ -1810,13 +1799,13 @@ end
|
|||
-- after_destruct
|
||||
-- Clears snowed dirtlike node below.
|
||||
function mcl_core.after_snow_destruct(pos)
|
||||
local nn = minetest.get_node(pos).name
|
||||
local nn = minetest_get_node(pos).name
|
||||
-- No-op if snow was replaced with snow
|
||||
if minetest.get_item_group(nn, "snow_cover") == 1 then
|
||||
if minetest_get_item_group(nn, "snow_cover") == 1 then
|
||||
return
|
||||
end
|
||||
local npos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local node = minetest.get_node(npos)
|
||||
local node = minetest_get_node(npos)
|
||||
mcl_core.clear_snow_dirt(npos, node)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_core
|
||||
description = Core items of MineClone 2: Basic biome blocks (dirt, sand, stones, etc.), derived items, glass, sugar cane, cactus, barrier, mining tools, hand, craftitems, and misc. items which don't really fit anywhere else.
|
||||
depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors, mcl_mapgen
|
||||
depends = mcl_autogroup, mcl_init, mcl_sounds, mcl_particles, mcl_util, mcl_worlds, doc_items, mcl_enchanting, mcl_colors, mcl_mapgen, mcl_time
|
||||
optional_depends = doc
|
||||
|
|
|
@ -11,7 +11,23 @@ else
|
|||
ice_drawtype = "normal"
|
||||
ice_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false
|
||||
end
|
||||
local mossnodes = {"mcl_core:stone", "mcl_core:granite", "mcl_core:granite_smooth", "mcl_core:diorite", "mcl_core:diorite_smooth", "mcl_core:andesite", "mcl_core:andesite_smooth", "mcl_deepslate:deepslate", --[[glowberries, ]]"mcl_core:dirt", "mcl_core:dirt_with_grass", "mcl_core:podzol", "mcl_core:coarse_dirt", "mcl_core:mycelium"}
|
||||
|
||||
local moss_nodes = {
|
||||
"mcl_core:stone",
|
||||
"mcl_core:granite",
|
||||
"mcl_core:granite_smooth",
|
||||
"mcl_core:diorite",
|
||||
"mcl_core:diorite_smooth",
|
||||
"mcl_core:andesite",
|
||||
"mcl_core:andesite_smooth",
|
||||
"mcl_deepslate:deepslate",
|
||||
--[[glowberries, ]]
|
||||
"mcl_core:dirt",
|
||||
"mcl_core:dirt_with_grass",
|
||||
"mcl_core:podzol",
|
||||
"mcl_core:coarse_dirt",
|
||||
"mcl_core:mycelium",
|
||||
}
|
||||
|
||||
mcl_core.fortune_drop_ore = {
|
||||
discrete_uniform_distribution = true,
|
||||
|
@ -1089,7 +1105,9 @@ minetest.register_node("mcl_core:snowblock", {
|
|||
_mcl_silk_touch_drop = true,
|
||||
})
|
||||
|
||||
minetest.register_node("mcl_core:moss", {
|
||||
local MOSS_ITEMSTRING = "mcl_core:moss"
|
||||
local MOSS_NODE = {name = MOSS_ITEMSTRING}
|
||||
minetest.register_node(MOSS_ITEMSTRING, {
|
||||
description = S("Moss"),
|
||||
_doc_items_longdesc = S("A moss block is a natural block that can be spread to some other blocks by using bone meal."),--TODO: Other desciption?
|
||||
_doc_items_hidden = false,
|
||||
|
@ -1101,41 +1119,41 @@ minetest.register_node("mcl_core:moss", {
|
|||
_mcl_blast_resistance = 0.1,
|
||||
_mcl_hardness = 0.1,
|
||||
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
|
||||
if player:get_wielded_item():get_name() == "mcl_dye:white" then
|
||||
if not minetest.is_creative_enabled(player) and not minetest.check_player_privs(player, "creative") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
|
||||
for i, j in pairs(minetest.find_nodes_in_area_under_air({x = pos.x-1, y = pos.y-1, z = pos.z-1}, {x = pos.x+1, y = pos.y+1, z = pos.z+1}, mossnodes)) do
|
||||
minetest.set_node(j, {name="mcl_core:moss"})
|
||||
end
|
||||
for i, j in pairs(minetest.find_nodes_in_area_under_air({x = pos.x-2, y = pos.y-1, z = pos.z-2}, {x = pos.x+2, y = pos.y+1, z = pos.z+2}, mossnodes)) do
|
||||
if math.random(1,3) == 1 then minetest.set_node(j, {name="mcl_core:moss"}) end
|
||||
end
|
||||
for i, j in pairs(minetest.find_nodes_in_area_under_air({x = pos.x-3, y = pos.y-1, z = pos.z-3}, {x = pos.x+3, y = pos.y+1, z = pos.z+3}, mossnodes)) do
|
||||
if math.random(1,9) == 1 then minetest.set_node(j, {name="mcl_core:moss"}) end
|
||||
end
|
||||
for i, j in pairs(minetest.find_nodes_in_area_under_air({x = pos.x-3, y = pos.y-1, z = pos.z-3}, {x = pos.x+3, y = pos.y+1, z = pos.z+3}, {"mcl_core:moss"})) do
|
||||
if math.random(1,2) == 1 then
|
||||
minetest.set_node({x=j.x,y=j.y+1,z=j.z} ,{name="mcl_flowers:tallgrass"})
|
||||
end
|
||||
end
|
||||
for i, j in pairs(minetest.find_nodes_in_area_under_air({x = pos.x-3, y = pos.y-1, z = pos.z-3}, {x = pos.x+3, y = pos.y+1, z = pos.z+3}, {"mcl_core:moss"})) do
|
||||
if math.random(1,4) == 1 then
|
||||
minetest.set_node({x=j.x,y=j.y+1,z=j.z}, {name="mcl_core:moss_carpet"})
|
||||
end
|
||||
end
|
||||
for i, j in pairs(minetest.find_nodes_in_area_under_air({x = pos.x-3, y = pos.y-1, z = pos.z-3}, {x = pos.x+3, y = pos.y+1, z = pos.z+3}, {"mcl_core:moss"})) do
|
||||
if math.random(1,10) == 1 then
|
||||
minetest.set_node({x=j.x,y=j.y+1,z=j.z} ,{name="mcl_flowers:double_grass"})
|
||||
minetest.set_node({x=j.x,y=j.y+2,z=j.z} ,{name="mcl_flowers:double_grass_top"})
|
||||
end
|
||||
end
|
||||
elseif minetest.registered_nodes[player:get_wielded_item():get_name()] then
|
||||
local pos = pos
|
||||
local x, y, z = pos.x, pos.y, pos.z
|
||||
local player_wielded_item = player:get_wielded_item()
|
||||
local item_name = player_wielded_item:get_name()
|
||||
if item_name == "mcl_dye:white" then
|
||||
if not minetest.is_creative_enabled(player) then
|
||||
itemstack:take_item()
|
||||
minetest.set_node(pointed_thing.above, {name=player:get_wielded_item():get_name()})
|
||||
end
|
||||
end,
|
||||
end
|
||||
for _, p in pairs(minetest.find_nodes_in_area_under_air({x=x-1, y=y-1, z=z-1}, {x=x+1, y=y+1, z=z+1}, moss_nodes)) do
|
||||
minetest.set_node(p, MOSS_NODE)
|
||||
end
|
||||
for _, p in pairs(minetest.find_nodes_in_area_under_air({x=x-2, y=y-2, z=z-2}, {x=x+2, y=y+2, z=z+2}, moss_nodes)) do
|
||||
if math.random(1,3) == 1 then minetest.set_node(p, MOSS_NODE) end
|
||||
end
|
||||
for _, p in pairs(minetest.find_nodes_in_area_under_air({x=x-3, y=y-3, z=z-3}, {x=x+3, y=y+3, z=z+3}, moss_nodes)) do
|
||||
if math.random(1,9) == 1 then minetest.set_node(p, MOSS_NODE) end
|
||||
end
|
||||
for _, p in pairs(minetest.find_nodes_in_area_under_air({x=x-3, y=y-3, z=z-3}, {x=x+3, y=y+3, z=z+3}, {MOSS_ITEMSTRING})) do
|
||||
if math.random(1,2) == 1 then
|
||||
minetest.set_node({x=p.x, y=p.y+1, z=p.z}, {name="mcl_flowers:tallgrass"})
|
||||
elseif math.random(1,4) == 1 then
|
||||
minetest.set_node({x=p.x, y=p.y+1, z=p.z}, {name="mcl_core:moss_carpet"})
|
||||
elseif math.random(1,10) == 1 then
|
||||
minetest.set_node({x=p.x, y=p.y+1, z=p.z}, {name="mcl_flowers:double_grass"})
|
||||
minetest.set_node({x=p.x, y=p.y+2, z=p.z}, {name="mcl_flowers:double_grass_top"})
|
||||
end
|
||||
end
|
||||
elseif minetest.registered_nodes[item_name] then
|
||||
if not minetest.is_creative_enabled(player) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
local set_pos = pointed_thing and pointed_thing.above or {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest.set_node(set_pos, {name = item_name})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("mcl_core:moss_carpet", {
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
@ -1,5 +0,0 @@
|
|||
# Hoppers
|
||||
This is the Hoppers mod for Minetest. It's just a clone of Minecraft hoppers, functions nearly identical to them minus mesecons making them stop and the way they're placed.
|
||||
|
||||
## Forum Topic
|
||||
- https://forum.minetest.net/viewtopic.php?f=11&t=12379
|
|
@ -1,9 +1,26 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local get_item_group = minetest.get_item_group
|
||||
|
||||
--[[ BEGIN OF NODE DEFINITIONS ]]
|
||||
local math_abs = math.abs
|
||||
local mcl_util_move_item_container = mcl_util.move_item_container
|
||||
local minetest_facedir_to_dir = minetest.facedir_to_dir
|
||||
local minetest_get_inventory = minetest.get_inventory
|
||||
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_objects_inside_radius = minetest.get_objects_inside_radius
|
||||
local minetest_registered_nodes = minetest.registered_nodes
|
||||
|
||||
local HOPPER = "mcl_hoppers:hopper"
|
||||
local HOPPER_SIDE = "mcl_hoppers:hopper_side"
|
||||
local GROUPS_TO_PUT_INTO_COMMON_SLOT = {
|
||||
[2] = true,
|
||||
[3] = true,
|
||||
[5] = true,
|
||||
[6] = true,
|
||||
}
|
||||
local GROUPS_TO_PUT_INTO_FUEL_SLOT = {
|
||||
[4] = true,
|
||||
}
|
||||
local mcl_hoppers_formspec =
|
||||
"size[9,7]"..
|
||||
"label[2,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Hopper"))).."]"..
|
||||
|
@ -25,44 +42,50 @@ local def_hopper = {
|
|||
groups = {pickaxey=1, container=2,deco_block=1,hopper=1},
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
-- FIXME: mcl_hoppers_hopper_inside.png is unused by hoppers.
|
||||
tiles = {"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png"},
|
||||
tiles = {
|
||||
"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png"
|
||||
},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
--funnel walls
|
||||
{-0.5, 0.0, 0.4, 0.5, 0.5, 0.5},
|
||||
{0.4, 0.0, -0.5, 0.5, 0.5, 0.5},
|
||||
{-0.5, 0.0, -0.5, -0.4, 0.5, 0.5},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, -0.4},
|
||||
{-0.5, 0.0, 0.4, 0.5, 0.5, 0.5,},
|
||||
{ 0.4, 0.0, -0.5, 0.5, 0.5, 0.5,},
|
||||
{-0.5, 0.0, -0.5, -0.4, 0.5, 0.5,},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, -0.4,},
|
||||
--funnel base
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.1, 0.5},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.1, 0.5,},
|
||||
--spout
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3},
|
||||
{-0.1, -0.3, -0.1, 0.1, -0.5, 0.1},
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3,},
|
||||
{-0.1, -0.3, -0.1, 0.1, -0.5, 0.1,},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
--funnel
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, 0.5},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, 0.5,},
|
||||
--spout
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3},
|
||||
{-0.1, -0.3, -0.1, 0.1, -0.5, 0.1},
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3,},
|
||||
{-0.1, -0.3, -0.1, 0.1, -0.5, 0.1,},
|
||||
},
|
||||
},
|
||||
is_ground_content = false,
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = minetest_get_meta(pos)
|
||||
meta:set_string("formspec", mcl_hoppers_formspec)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 5)
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = minetest_get_meta(pos)
|
||||
local meta2 = meta:to_table()
|
||||
meta:from_table(oldmetadata)
|
||||
local inv = meta:get_inventory()
|
||||
|
@ -120,10 +143,8 @@ local def_hopper = {
|
|||
_mcl_hardness = 3,
|
||||
}
|
||||
|
||||
-- Redstone variants (on/off) of downwards hopper.
|
||||
-- Note a hopper is enabled when it is *not* supplied with redstone power and disabled when it is supplied with redstone power.
|
||||
|
||||
-- Enabled downwards hopper
|
||||
|
||||
local def_hopper_enabled = table.copy(def_hopper)
|
||||
def_hopper_enabled.description = S("Hopper")
|
||||
def_hopper_enabled._tt_help = S("5 inventory slots").."\n"..S("Collects items from above, moves items to container below").."\n"..S("Can be disabled with redstone power")
|
||||
|
@ -140,8 +161,8 @@ def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing)
|
|||
local upos = pointed_thing.under
|
||||
local apos = pointed_thing.above
|
||||
|
||||
local uposnode = minetest.get_node(upos)
|
||||
local uposnodedef = minetest.registered_nodes[uposnode.name]
|
||||
local uposnode = minetest_get_node(upos)
|
||||
local uposnodedef = minetest_registered_nodes[uposnode.name]
|
||||
if not uposnodedef then return itemstack end
|
||||
-- Use pointed node's on_rightclick function first, if present
|
||||
if placer and not placer:get_player_control().sneak then
|
||||
|
@ -150,26 +171,16 @@ def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing)
|
|||
end
|
||||
end
|
||||
|
||||
local x = upos.x - apos.x
|
||||
local z = upos.z - apos.z
|
||||
|
||||
local fake_itemstack = ItemStack(itemstack)
|
||||
local dx = apos.x - upos.x
|
||||
local dz = apos.z - upos.z
|
||||
local param2
|
||||
if x == -1 then
|
||||
fake_itemstack:set_name("mcl_hoppers:hopper_side")
|
||||
param2 = 0
|
||||
elseif x == 1 then
|
||||
fake_itemstack:set_name("mcl_hoppers:hopper_side")
|
||||
param2 = 2
|
||||
elseif z == -1 then
|
||||
fake_itemstack:set_name("mcl_hoppers:hopper_side")
|
||||
param2 = 3
|
||||
elseif z == 1 then
|
||||
fake_itemstack:set_name("mcl_hoppers:hopper_side")
|
||||
param2 = 1
|
||||
if (dx ~= 0) or (dz ~= 0) then
|
||||
param2 = minetest.dir_to_facedir({x = dx, y = 0, z = dz})
|
||||
fake_itemstack:set_name(HOPPER_SIDE)
|
||||
end
|
||||
local itemstack,_ = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2)
|
||||
itemstack:set_name("mcl_hoppers:hopper")
|
||||
local itemstack, _ = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2)
|
||||
itemstack:set_name(HOPPER)
|
||||
return itemstack
|
||||
end
|
||||
def_hopper_enabled.mesecons = {
|
||||
|
@ -180,77 +191,84 @@ def_hopper_enabled.mesecons = {
|
|||
},
|
||||
}
|
||||
|
||||
minetest.register_node("mcl_hoppers:hopper", def_hopper_enabled)
|
||||
minetest.register_node(HOPPER, def_hopper_enabled)
|
||||
|
||||
-- Disabled downwards hopper
|
||||
|
||||
local def_hopper_disabled = table.copy(def_hopper)
|
||||
def_hopper_disabled.description = S("Disabled Hopper")
|
||||
def_hopper_disabled.inventory_image = nil
|
||||
def_hopper_disabled._doc_items_create_entry = false
|
||||
def_hopper_disabled.groups.not_in_creative_inventory = 1
|
||||
def_hopper_disabled.drop = "mcl_hoppers:hopper"
|
||||
def_hopper_disabled.drop = HOPPER
|
||||
def_hopper_disabled.mesecons = {
|
||||
effector = {
|
||||
action_off = function(pos, node)
|
||||
minetest.swap_node(pos, {name="mcl_hoppers:hopper", param2=node.param2})
|
||||
minetest.swap_node(pos, {name=HOPPER, param2=node.param2})
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
minetest.register_node("mcl_hoppers:hopper_disabled", def_hopper_disabled)
|
||||
|
||||
-- Sidewadrs hopper (base definition)
|
||||
|
||||
|
||||
local on_rotate
|
||||
if minetest.get_modpath("screwdriver") then
|
||||
on_rotate = screwdriver.rotate_simple
|
||||
end
|
||||
|
||||
-- Sidewars hopper (base definition)
|
||||
local def_hopper_side = {
|
||||
_doc_items_create_entry = false,
|
||||
drop = "mcl_hoppers:hopper",
|
||||
groups = {pickaxey=1, container=2,not_in_creative_inventory=1,hopper=2},
|
||||
drop = HOPPER,
|
||||
groups = {
|
||||
container = 2,
|
||||
hopper = 2,
|
||||
not_in_creative_inventory = 1,
|
||||
pickaxey = 1,
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
tiles = {"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png"},
|
||||
tiles = {
|
||||
"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
"mcl_hoppers_hopper_outside.png",
|
||||
},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
--funnel walls
|
||||
{-0.5, 0.0, 0.4, 0.5, 0.5, 0.5},
|
||||
{0.4, 0.0, -0.5, 0.5, 0.5, 0.5},
|
||||
{-0.5, 0.0, -0.5, -0.4, 0.5, 0.5},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, -0.4},
|
||||
{-0.5, 0.0, 0.4, 0.5, 0.5, 0.5,},
|
||||
{ 0.4, 0.0, -0.5, 0.5, 0.5, 0.5,},
|
||||
{-0.5, 0.0, -0.5, -0.4, 0.5, 0.5,},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, -0.4,},
|
||||
--funnel base
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.1, 0.5},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.1, 0.5,},
|
||||
--spout
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3},
|
||||
{-0.5, -0.3, -0.1, 0.1, -0.1, 0.1},
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3,},
|
||||
{-0.1, -0.3, -0.5, 0.1, -0.1, 0.1,},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
--funnel
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, 0.5},
|
||||
{-0.5, 0.0, -0.5, 0.5, 0.5, 0.5,},
|
||||
--spout
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3},
|
||||
{-0.5, -0.3, -0.1, 0.1, -0.1, 0.1},
|
||||
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3,},
|
||||
{-0.1, -0.3, -0.5, 0.1, -0.1, 0.1,},
|
||||
},
|
||||
},
|
||||
is_ground_content = false,
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = minetest_get_meta(pos)
|
||||
meta:set_string("formspec", mcl_hoppers_formspec)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 5)
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = minetest_get_meta(pos)
|
||||
local meta2 = meta
|
||||
meta:from_table(oldmetadata)
|
||||
local inv = meta:get_inventory()
|
||||
|
@ -302,13 +320,15 @@ local def_hopper_side = {
|
|||
minetest.log("action", player:get_player_name()..
|
||||
" takes stuff from mcl_hoppers at "..minetest.pos_to_string(pos))
|
||||
end,
|
||||
on_rotate = on_rotate,
|
||||
on_rotate = screwdriver.rotate_simple,
|
||||
sounds = mcl_sounds.node_sound_metal_defaults(),
|
||||
|
||||
_mcl_blast_resistance = 4.8,
|
||||
_mcl_hardness = 3,
|
||||
}
|
||||
|
||||
-- Enabled sidewards hopper
|
||||
|
||||
local def_hopper_side_enabled = table.copy(def_hopper_side)
|
||||
def_hopper_side_enabled.description = S("Side Hopper")
|
||||
def_hopper_side_enabled.mesecons = {
|
||||
|
@ -318,53 +338,105 @@ def_hopper_side_enabled.mesecons = {
|
|||
end,
|
||||
},
|
||||
}
|
||||
minetest.register_node("mcl_hoppers:hopper_side", def_hopper_side_enabled)
|
||||
minetest.register_node(HOPPER_SIDE, def_hopper_side_enabled)
|
||||
|
||||
-- Disabled sidewards hopper
|
||||
|
||||
local def_hopper_side_disabled = table.copy(def_hopper_side)
|
||||
def_hopper_side_disabled.description = S("Disabled Side Hopper")
|
||||
def_hopper_side_disabled.mesecons = {
|
||||
effector = {
|
||||
action_off = function(pos, node)
|
||||
minetest.swap_node(pos, {name="mcl_hoppers:hopper_side", param2=node.param2})
|
||||
minetest.swap_node(pos, {name=HOPPER_SIDE, param2=node.param2})
|
||||
end,
|
||||
},
|
||||
}
|
||||
minetest.register_node("mcl_hoppers:hopper_side_disabled", def_hopper_side_disabled)
|
||||
|
||||
--[[ END OF NODE DEFINITIONS ]]
|
||||
|
||||
--[[ BEGIN OF ABM DEFINITONS ]]
|
||||
|
||||
-- Make hoppers suck in dropped items
|
||||
minetest.register_abm({
|
||||
label = "Hoppers suck in dropped items",
|
||||
nodenames = {"mcl_hoppers:hopper","mcl_hoppers:hopper_side"},
|
||||
interval = 1.0,
|
||||
label = "Hopper",
|
||||
nodenames = {
|
||||
HOPPER,
|
||||
HOPPER_SIDE,
|
||||
},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
if not minetest.registered_items[abovenode.name] then return end
|
||||
-- Don't bother checking item enties if node above is a container (should save some CPU)
|
||||
if get_item_group(abovenode.name, "container") then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
action = function(pos, node)
|
||||
local pos = pos
|
||||
local meta = minetest_get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if not inv then return end
|
||||
|
||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, 2)) do
|
||||
local entity = object:get_luaentity()
|
||||
if not object:is_player() and entity and entity.name == "__builtin:item" and not entity._removed then
|
||||
if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
|
||||
-- Item must get sucked in when the item just TOUCHES the block above the hopper
|
||||
-- This is the reason for the Y calculation.
|
||||
-- Test: Items on farmland and slabs get sucked, but items on full blocks don't
|
||||
local posob = object:get_pos()
|
||||
local posob_miny = posob.y + object:get_properties().collisionbox[2]
|
||||
if math.abs(posob.x-pos.x) <= 0.5 and (posob_miny-pos.y < 1.5 and posob.y-pos.y >= 0.3) then
|
||||
entity._removed = true
|
||||
entity.itemstring = ""
|
||||
object:remove()
|
||||
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
|
||||
local x, y, z = pos.x, pos.y, pos.z
|
||||
|
||||
-- Move an item from the hopper into the container to which the hopper points to
|
||||
local dst_pos
|
||||
if node.name == HOPPER then
|
||||
dst_pos = {x = x, y = y - 1, z = z}
|
||||
else
|
||||
local param2 = node.param2
|
||||
local dir = minetest_facedir_to_dir(param2)
|
||||
if not dir then return end
|
||||
dst_pos = {x = x - dir.x, y = y, z = z - dir.z}
|
||||
end
|
||||
local dst_node = minetest_get_node(dst_pos)
|
||||
local dst_node_name = dst_node.name
|
||||
local dst_container_group = minetest_get_item_group(dst_node_name, "container")
|
||||
if GROUPS_TO_PUT_INTO_COMMON_SLOT[dst_container_group] then
|
||||
mcl_util_move_item_container(pos, dst_pos)
|
||||
elseif GROUPS_TO_PUT_INTO_FUEL_SLOT[dst_container_group] then
|
||||
local sinv = minetest_get_inventory({type="node", pos = pos})
|
||||
local dinv = minetest_get_inventory({type="node", pos = dst_pos})
|
||||
local slot_id,_ = mcl_util.get_eligible_transfer_item_slot(
|
||||
sinv,
|
||||
"main",
|
||||
dinv,
|
||||
"fuel",
|
||||
function(itemstack, src_inventory, src_list, dst_inventory, dst_list)
|
||||
-- Returns true if itemstack is fuel, but not for lava bucket if destination already has one
|
||||
if not mcl_util.is_fuel(itemstack) then return false end
|
||||
if itemstack:get_name() ~= "mcl_buckets:bucket_lava" then return true end
|
||||
return dst_inventory:is_empty(dst_list)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local y_above = y + 1
|
||||
local pos_above = {x = x, y = y_above, z = z}
|
||||
local above_node = minetest_get_node(pos_above)
|
||||
local above_node_name = above_node.name
|
||||
local above_container_group = minetest_get_item_group(above_node_name, "container")
|
||||
if above_container_group ~= 0 then
|
||||
-- Suck an item from the container above into the hopper
|
||||
if not mcl_util_move_item_container(pos_above, pos)
|
||||
and above_container_group == 4 then
|
||||
local finv = minetest_get_inventory({type="node", pos = pos_above})
|
||||
if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then
|
||||
mcl_util_move_item_container(pos_above, pos, "fuel")
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Suck in dropped items
|
||||
local y_top_touch_to_suck = y_above + 0.5
|
||||
for _, object in pairs(minetest_get_objects_inside_radius(pos_above, 1)) do
|
||||
if not object:is_player() then
|
||||
local entity = object:get_luaentity()
|
||||
local entity_name = entity and entity.name
|
||||
if entity_name == "__builtin:item" then
|
||||
local itemstring = entity.itemstring
|
||||
if itemstring and itemstring ~= "" and inv:room_for_item("main", ItemStack(itemstring)) then
|
||||
local object_pos = object:get_pos()
|
||||
local object_pos_y = object_pos.y
|
||||
local object_collisionbox = object:get_properties().collisionbox
|
||||
local touches_from_above = object_pos_y + object_collisionbox[2] <= y_top_touch_to_suck
|
||||
if touches_from_above
|
||||
and (math_abs(object_pos.x - x) <= 0.5)
|
||||
and (math_abs(object_pos.z - z) <= 0.5)
|
||||
then
|
||||
object:remove()
|
||||
inv:add_item("main", ItemStack(itemstring))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -372,116 +444,8 @@ minetest.register_abm({
|
|||
end,
|
||||
})
|
||||
|
||||
-- Returns true if itemstack is fuel, but not for lava bucket if destination already has one
|
||||
local is_transferrable_fuel = function(itemstack, src_inventory, src_list, dst_inventory, dst_list)
|
||||
if mcl_util.is_fuel(itemstack) then
|
||||
if itemstack:get_name() == "mcl_buckets:bucket_lava" then
|
||||
return dst_inventory:is_empty(dst_list)
|
||||
else
|
||||
return true
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Hopper/container item exchange",
|
||||
nodenames = {"mcl_hoppers:hopper"},
|
||||
neighbors = {"group:container"},
|
||||
interval = 1.0,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
-- Get node pos' for item transfer
|
||||
local uppos = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||
local downpos = {x=pos.x,y=pos.y-1,z=pos.z}
|
||||
|
||||
-- Suck an item from the container above into the hopper
|
||||
local upnode = minetest.get_node(uppos)
|
||||
if not minetest.registered_nodes[upnode.name] then return end
|
||||
local g = get_item_group(upnode.name, "container")
|
||||
local sucked = mcl_util.move_item_container(uppos, pos)
|
||||
|
||||
-- Also suck in non-fuel items from furnace fuel slot
|
||||
if not sucked and g == 4 then
|
||||
local finv = minetest.get_inventory({type="node", pos=uppos})
|
||||
if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then
|
||||
mcl_util.move_item_container(uppos, pos, "fuel")
|
||||
end
|
||||
end
|
||||
|
||||
-- Move an item from the hopper into container below
|
||||
local downnode = minetest.get_node(downpos)
|
||||
if not minetest.registered_nodes[downnode.name] then return end
|
||||
mcl_util.move_item_container(pos, downpos)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Side-hopper/container item exchange",
|
||||
nodenames = {"mcl_hoppers:hopper_side"},
|
||||
neighbors = {"group:container"},
|
||||
interval = 1.0,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
-- Determine to which side the hopper is facing, get nodes
|
||||
local face = minetest.get_node(pos).param2
|
||||
local front = {}
|
||||
if face == 0 then
|
||||
front = {x=pos.x-1,y=pos.y,z=pos.z}
|
||||
elseif face == 1 then
|
||||
front = {x=pos.x,y=pos.y,z=pos.z+1}
|
||||
elseif face == 2 then
|
||||
front = {x=pos.x+1,y=pos.y,z=pos.z}
|
||||
elseif face == 3 then
|
||||
front = {x=pos.x,y=pos.y,z=pos.z-1}
|
||||
end
|
||||
local above = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||
local downpos = {x=pos.x,y=pos.y-1,z=pos.z}
|
||||
|
||||
local frontnode = minetest.get_node(front)
|
||||
if not minetest.registered_nodes[frontnode.name] then return end
|
||||
|
||||
-- Suck an item from the container above into the hopper
|
||||
local abovenode = minetest.get_node(above)
|
||||
if not minetest.registered_nodes[abovenode.name] then return end
|
||||
local g = get_item_group(abovenode.name, "container")
|
||||
local sucked = mcl_util.move_item_container(above, pos)
|
||||
|
||||
-- Also suck in non-fuel items from furnace fuel slot
|
||||
if not sucked and g == 4 then
|
||||
local finv = minetest.get_inventory({type="node", pos=above})
|
||||
if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then
|
||||
mcl_util.move_item_container(above, pos, "fuel")
|
||||
end
|
||||
end
|
||||
|
||||
-- Try to move an item below before moving it sideways
|
||||
local downnode = minetest.get_node(downpos)
|
||||
|
||||
if minetest.registered_nodes[downnode.name] and
|
||||
mcl_util.move_item_container(pos, downpos) then return end
|
||||
|
||||
-- Move an item from the hopper into the container to which the hopper points to
|
||||
local g = get_item_group(frontnode.name, "container")
|
||||
if g == 2 or g == 3 or g == 5 or g == 6 then
|
||||
mcl_util.move_item_container(pos, front)
|
||||
elseif g == 4 then
|
||||
-- Put fuel into fuel slot
|
||||
local sinv = minetest.get_inventory({type="node", pos = pos})
|
||||
local dinv = minetest.get_inventory({type="node", pos = front})
|
||||
local slot_id,_ = mcl_util.get_eligible_transfer_item_slot(sinv, "main", dinv, "fuel", is_transferrable_fuel)
|
||||
if slot_id then
|
||||
mcl_util.move_item_container(pos, front, nil, slot_id, "fuel")
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mcl_hoppers:hopper",
|
||||
output = HOPPER,
|
||||
recipe = {
|
||||
{"mcl_core:iron_ingot","","mcl_core:iron_ingot"},
|
||||
{"mcl_core:iron_ingot","mcl_chests:chest","mcl_core:iron_ingot"},
|
||||
|
@ -489,21 +453,20 @@ minetest.register_craft({
|
|||
}
|
||||
})
|
||||
|
||||
-- Add entry aliases for the Help
|
||||
if minetest.get_modpath("doc") then
|
||||
doc.add_entry_alias("nodes", "mcl_hoppers:hopper", "nodes", "mcl_hoppers:hopper_side")
|
||||
doc.add_entry_alias("nodes", HOPPER, "nodes", HOPPER_SIDE)
|
||||
end
|
||||
|
||||
-- Legacy
|
||||
minetest.register_alias("mcl_hoppers:hopper_item", "mcl_hoppers:hopper")
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "Update hopper formspecs (0.60.0",
|
||||
name = "mcl_hoppers:update_formspec_0_60_0",
|
||||
nodenames = { "group:hopper" },
|
||||
run_at_every_load = false,
|
||||
action = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = minetest_get_meta(pos)
|
||||
meta:set_string("formspec", mcl_hoppers_formspec)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Legacy
|
||||
minetest.register_alias("mcl_hoppers:hopper_item", HOPPER)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
name = mcl_hoppers
|
||||
author = jordan4ibanez
|
||||
description = It's just a clone of Minecraft hoppers, functions nearly identical to them minus mesecons making them stop and the way they're placed.
|
||||
depends = mcl_core, mcl_formspec, mcl_sounds, mcl_util
|
||||
optional_depends = doc, screwdriver
|
||||
|
|
|
@ -14,6 +14,7 @@ mcl_shields = {
|
|||
enchantments = {"mending", "unbreaking"},
|
||||
players = {},
|
||||
}
|
||||
local players = mcl_shields.players
|
||||
|
||||
local interact_priv = minetest.registered_privileges.interact
|
||||
interact_priv.give_to_singleplayer = false
|
||||
|
@ -110,7 +111,7 @@ end
|
|||
|
||||
function mcl_shields.is_blocking(obj)
|
||||
if not mcl_util or not mcl_util.is_player(obj) then return end
|
||||
local blocking = mcl_shields.players[obj].blocking
|
||||
local blocking = players[obj].blocking
|
||||
if blocking > 0 then
|
||||
local shieldstack = obj:get_wielded_item()
|
||||
if blocking == 1 then
|
||||
|
@ -155,7 +156,7 @@ local function modify_shield(player, vpos, vrot, i)
|
|||
if i == 1 then
|
||||
arm = "Left"
|
||||
end
|
||||
local player_data = mcl_shields.players[player]
|
||||
local player_data = players[player]
|
||||
if not player_data then return end
|
||||
local shields = player_data.shields
|
||||
if not shields then return end
|
||||
|
@ -178,7 +179,10 @@ local function set_shield(player, block, i)
|
|||
modify_shield(player, vector.new(3, -5, 0), vector.new(0, 0, 0), i)
|
||||
end
|
||||
end
|
||||
local shield = mcl_shields.players[player].shields[i]
|
||||
local player_data = players[player]
|
||||
if not player_data then return end
|
||||
local player_shields = player_data.shields
|
||||
local shield = player_shields[i]
|
||||
if not shield then return end
|
||||
local luaentity = shield:get_luaentity()
|
||||
if not luaentity then return end
|
||||
|
@ -219,12 +223,12 @@ end
|
|||
local function add_shield_entity(player, i)
|
||||
local shield = minetest.add_entity(player:get_pos(), "mcl_shields:shield_entity")
|
||||
shield:get_luaentity()._shield_number = i
|
||||
mcl_shields.players[player].shields[i] = shield
|
||||
players[player].shields[i] = shield
|
||||
set_shield(player, false, i)
|
||||
end
|
||||
|
||||
local function remove_shield_entity(player, i)
|
||||
local shields = mcl_shields.players[player].shields
|
||||
local shields = players[player].shields
|
||||
if shields[i] then
|
||||
shields[i]:remove()
|
||||
shields[i] = nil
|
||||
|
@ -232,7 +236,7 @@ local function remove_shield_entity(player, i)
|
|||
end
|
||||
|
||||
local function handle_blocking(player)
|
||||
local player_shield = mcl_shields.players[player]
|
||||
local player_shield = players[player]
|
||||
local rmb = player:get_player_control().RMB
|
||||
if rmb then
|
||||
local shield_in_offhand = mcl_shields.wielding_shield(player, 1)
|
||||
|
@ -274,7 +278,7 @@ local function handle_blocking(player)
|
|||
end
|
||||
|
||||
local function update_shield_entity(player, blocking, i)
|
||||
local shield = mcl_shields.players[player].shields[i]
|
||||
local shield = players[player].shields[i]
|
||||
if mcl_shields.wielding_shield(player, i) then
|
||||
if not shield then
|
||||
add_shield_entity(player, i)
|
||||
|
@ -378,7 +382,7 @@ end)
|
|||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
shield_hud[player] = nil
|
||||
mcl_shields.players[player] = nil
|
||||
players[player] = nil
|
||||
end)
|
||||
|
||||
minetest.register_craft({
|
||||
|
@ -468,7 +472,7 @@ minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv
|
|||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
mcl_shields.players[player] = {
|
||||
players[player] = {
|
||||
shields = {},
|
||||
blocking = 0,
|
||||
}
|
||||
|
|
|
@ -62,7 +62,6 @@ local spawn_trident = function(player)
|
|||
durability = durability * (unbreaking + 1)
|
||||
end
|
||||
wielditem:add_wear(65535/durability)
|
||||
minetest.chat_send_all(wielditem:get_wear())
|
||||
obj:set_velocity(vector.multiply(player:get_look_dir(), 20))
|
||||
obj:set_acceleration({x=0, y=-GRAVITY, z=0})
|
||||
obj:set_yaw(yaw)
|
||||
|
@ -78,10 +77,10 @@ minetest.register_tool("mcl_tridents:trident", {
|
|||
stack_max = 1,
|
||||
groups = {weapon=1,weapon_ranged=1,trident=1,enchantability=1},
|
||||
_mcl_uses = TRIDENT_DURABILITY,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
spawn_trident(placer)
|
||||
end,
|
||||
on_secondary_use = function(itemstack, user, pointed_thing)
|
||||
spawn_trident(user)
|
||||
end
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
spawn_trident(placer)
|
||||
end,
|
||||
on_secondary_use = function(itemstack, user, pointed_thing)
|
||||
spawn_trident(user)
|
||||
end
|
||||
})
|
||||
|
|
|
@ -3045,8 +3045,8 @@ local function register_decorations()
|
|||
octaves = 3,
|
||||
persist = 0.6
|
||||
},
|
||||
y_min = 4,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
spawn_by = "air",
|
||||
num_spawn_by = 8,
|
||||
decoration = "mcl_core:cactus",
|
||||
biomes = {"Desert",
|
||||
"Mesa","Mesa_sandlevel",
|
||||
|
|
|
@ -670,8 +670,8 @@ local function register_mgv6_decorations()
|
|||
octaves = 3,
|
||||
persist = 0.6
|
||||
},
|
||||
y_min = 4,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
spawn_by = "air",
|
||||
num_spawn_by = 8,
|
||||
decoration = "mcl_core:cactus",
|
||||
height = 1,
|
||||
height_max = 3,
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
local chance_per_chunk = 400
|
||||
local noise_multiplier = 2.5
|
||||
local random_offset = 9159
|
||||
local scanning_ratio = 0.001
|
||||
local struct_threshold = 396
|
||||
local struct_threshold = 393.91
|
||||
|
||||
local mcl_structures_get_perlin_noise_level = mcl_structures.get_perlin_noise_level
|
||||
local minetest_find_nodes_in_area = minetest.find_nodes_in_area
|
||||
|
@ -13,6 +10,223 @@ local minetest_swap_node = minetest.swap_node
|
|||
local math_round = math.round
|
||||
local math_abs = math.abs
|
||||
|
||||
local function insert_times(how_many_times, what, where)
|
||||
for i = 1, how_many_times do
|
||||
where[#where + 1] = what
|
||||
end
|
||||
end
|
||||
|
||||
local function create_probability_picker(table_of_how_many_times_what)
|
||||
local picker = {}
|
||||
for _, v in pairs(table_of_how_many_times_what) do
|
||||
insert_times(v[1], v[2], picker)
|
||||
end
|
||||
return picker
|
||||
end
|
||||
|
||||
local STONE_DECOR = {
|
||||
"mcl_core:stonebrickcarved",
|
||||
"mcl_blackstone:blackstone_chiseled_polished",
|
||||
}
|
||||
local PANE_OR_CHAIN = {
|
||||
"xpanes:bar",
|
||||
"mcl_lanterns:chain",
|
||||
}
|
||||
local PANE_OR_CHAIN_FLAT = {
|
||||
"xpanes:bar_flat",
|
||||
"mcl_lanterns:chain",
|
||||
}
|
||||
local STAIR1 = {
|
||||
"mcl_stairs:stair_stonebrickcracked",
|
||||
|
||||
-- TODO: stair_blackstone_brick_polished_cracked:
|
||||
"mcl_stairs:stair_deepslate_bricks",
|
||||
}
|
||||
local STAIR2 = {
|
||||
"mcl_stairs:stair_stonebrickmossy",
|
||||
"mcl_stairs:stair_blackstone_brick_polished",
|
||||
}
|
||||
local STAIR3 = {
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_blackstone_chiseled_polished",
|
||||
}
|
||||
local STAIR4 = {
|
||||
"mcl_stairs:stair_stonebrick",
|
||||
"mcl_stairs:stair_blackstone_brick_polished",
|
||||
}
|
||||
local STAIR_OUTER1 = {
|
||||
"mcl_stairs:stair_stonebrickcracked_outer",
|
||||
|
||||
-- TODO: stair_blackstone_brick_polished_cracked_outer:
|
||||
"mcl_stairs:stair_deepslate_bricks_outer",
|
||||
}
|
||||
local STAIR_OUTER2 = {
|
||||
"mcl_stairs:stair_stonebrickmossy_outer",
|
||||
"mcl_stairs:stair_blackstone_brick_polished_outer",
|
||||
}
|
||||
local STAIR_OUTER3 = {
|
||||
"mcl_stairs:stair_stone_rough_outer",
|
||||
"mcl_stairs:stair_blackstone_chiseled_polished_outer",
|
||||
}
|
||||
local STAIR_OUTER4 = {
|
||||
"mcl_stairs:stair_stonebrick_outer",
|
||||
"mcl_stairs:stair_blackstone_brick_polished_outer",
|
||||
}
|
||||
local TOP_DECOR1 = {
|
||||
"mcl_core:goldblock",
|
||||
"mcl_core:goldblock",
|
||||
}
|
||||
local TOP_DECOR2 = {
|
||||
"mcl_core:stone_with_gold",
|
||||
"mcl_core:stone_with_gold",
|
||||
}
|
||||
local STONE1 = {
|
||||
"mcl_core:stonebrickcracked",
|
||||
|
||||
-- TODO: polished_blackstone_brick_cracked:
|
||||
"mcl_deepslate:deepslate_bricks_cracked",
|
||||
}
|
||||
local STONE2 = {
|
||||
"mcl_core:stonebrickmossy",
|
||||
"mcl_blackstone:blackstone_brick_polished",
|
||||
}
|
||||
local STONE3 = {
|
||||
"mcl_nether:magma",
|
||||
"mcl_core:packed_ice",
|
||||
}
|
||||
local STONE4 = {
|
||||
"mcl_core:stonebrick",
|
||||
"mcl_blackstone:blackstone_brick_polished",
|
||||
}
|
||||
local STONE5 = {
|
||||
"mcl_core:stone",
|
||||
"mcl_blackstone:blackstone",
|
||||
}
|
||||
local STONE6 = {
|
||||
"mcl_core:cobble",
|
||||
"mcl_blackstone:basalt_polished",
|
||||
}
|
||||
local STONE7 = {
|
||||
"mcl_core:mossycobble",
|
||||
"mcl_blackstone:blackstone_chiseled_polished",
|
||||
}
|
||||
local SLAB_TOP1 = {
|
||||
"mcl_stairs:slab_stonebrickcracked_top",
|
||||
|
||||
-- TODO: slab_polished_blackstone_brick_cracked_top:
|
||||
"mcl_stairs:slab_goldblock_top",
|
||||
}
|
||||
local SLAB_TOP2 = {
|
||||
"mcl_stairs:slab_stonebrickmossy_top",
|
||||
"mcl_stairs:slab_blackstone_brick_polished_top",
|
||||
}
|
||||
local SLAB_TOP3 = {
|
||||
"mcl_stairs:slab_stone_top",
|
||||
"mcl_stairs:slab_blackstone_top",
|
||||
}
|
||||
local SLAB_TOP4 = {
|
||||
"mcl_stairs:slab_stonebrick_top",
|
||||
"mcl_stairs:slab_blackstone_brick_polished_top",
|
||||
}
|
||||
local SLAB1 = {
|
||||
"mcl_stairs:slab_stone",
|
||||
"mcl_stairs:slab_blackstone",
|
||||
}
|
||||
local SLAB2 = {
|
||||
"mcl_stairs:slab_stonebrick",
|
||||
"mcl_stairs:slab_blackstone_brick_polished",
|
||||
}
|
||||
local SLAB3 = {
|
||||
"mcl_stairs:slab_stonebrickcracked",
|
||||
|
||||
-- TODO: slab_polished_blackstone_brick_cracked:
|
||||
"mcl_stairs:slab_goldblock",
|
||||
}
|
||||
local SLAB4 = {
|
||||
"mcl_stairs:slab_stonebrickmossy",
|
||||
"mcl_stairs:slab_blackstone_brick_polished",
|
||||
}
|
||||
local GARBAGE1 = {
|
||||
"mcl_nether:netherrack",
|
||||
"mcl_core:stone",
|
||||
}
|
||||
local LAVA_SOURCE = {
|
||||
"mcl_nether:nether_lava_source",
|
||||
"mcl_core:lava_source",
|
||||
}
|
||||
local GARBAGE3 = {
|
||||
"mcl_nether:magma",
|
||||
"mcl_nether:magma",
|
||||
}
|
||||
|
||||
local stair_set_for_frame = create_probability_picker({
|
||||
{ 3, STAIR1,},
|
||||
{ 1, STAIR2,},
|
||||
{ 1, STAIR3,},
|
||||
{10, STAIR4,},
|
||||
})
|
||||
local stone_set_for_frame = create_probability_picker({
|
||||
{ 3, STONE1,},
|
||||
{ 1, STONE2,},
|
||||
{ 1, STONE3,},
|
||||
{10, STONE4,},
|
||||
})
|
||||
local slab_set_for_frame = create_probability_picker({
|
||||
{ 3, SLAB_TOP1,},
|
||||
{ 1, SLAB_TOP2,},
|
||||
{ 1, SLAB_TOP3,},
|
||||
{10, SLAB_TOP4,},
|
||||
})
|
||||
local stair_set_for_stairs = create_probability_picker({
|
||||
{ 1, STAIR1,},
|
||||
{ 2, STAIR2,},
|
||||
{ 7, STAIR3,},
|
||||
{ 3, STAIR4,},
|
||||
})
|
||||
local top_decoration_list = create_probability_picker({
|
||||
{ 2, TOP_DECOR1,},
|
||||
{ 1, TOP_DECOR2,},
|
||||
})
|
||||
local node_garbage = create_probability_picker({
|
||||
{ 4, GARBAGE1,},
|
||||
{ 1, LAVA_SOURCE,},
|
||||
{ 1, GARBAGE3,},
|
||||
})
|
||||
local stair_replacement_list = {
|
||||
"air",
|
||||
"group:water",
|
||||
"group:lava",
|
||||
"group:buildable_to",
|
||||
"group:deco_block",
|
||||
}
|
||||
local stair_outer_names = {
|
||||
STAIR_OUTER1,
|
||||
STAIR_OUTER2,
|
||||
STAIR_OUTER3,
|
||||
STAIR_OUTER4,
|
||||
}
|
||||
local stair_content = create_probability_picker({
|
||||
{1, LAVA_SOURCE,},
|
||||
{5, STONE5,},
|
||||
{1, STONE4,},
|
||||
{1, STONE3,},
|
||||
{2, GARBAGE1,},
|
||||
})
|
||||
local stair_content_bottom = create_probability_picker({
|
||||
{2, STONE3,},
|
||||
{4, GARBAGE1,},
|
||||
})
|
||||
local slabs = create_probability_picker({
|
||||
{5, SLAB1,},
|
||||
{2, SLAB2,},
|
||||
{1, SLAB3,},
|
||||
{1, SLAB4,},
|
||||
})
|
||||
local stones = create_probability_picker({
|
||||
{3, STONE5,},
|
||||
{1, STONE6,},
|
||||
{1, STONE7,},
|
||||
})
|
||||
|
||||
local rotation_to_orientation = {
|
||||
["0"] = 1,
|
||||
|
@ -28,39 +242,11 @@ local rotation_to_param2 = {
|
|||
["270"] = 2,
|
||||
}
|
||||
|
||||
local node_top = {
|
||||
"mcl_core:goldblock",
|
||||
"mcl_core:stone_with_gold",
|
||||
"mcl_core:goldblock",
|
||||
}
|
||||
|
||||
local node_garbage = {
|
||||
"mcl_nether:netherrack",
|
||||
"mcl_core:lava_source",
|
||||
"mcl_nether:netherrack",
|
||||
"mcl_nether:netherrack",
|
||||
"mcl_nether:magma",
|
||||
"mcl_nether:netherrack",
|
||||
}
|
||||
|
||||
local stone1 = {name = "mcl_core:stonebrickcracked"}
|
||||
local stone2 = {name = "mcl_core:stonebrickmossy"}
|
||||
local stone3 = {name = "mcl_nether:magma"}
|
||||
local stone4 = {name = "mcl_core:stonebrick"}
|
||||
|
||||
local slab1 = {name = "mcl_stairs:slab_stonebrickcracked_top"}
|
||||
local slab2 = {name = "mcl_stairs:slab_stonebrickmossy_top"}
|
||||
local slab3 = {name = "mcl_stairs:slab_stone_top"}
|
||||
local slab4 = {name = "mcl_stairs:slab_stonebrick_top"}
|
||||
|
||||
local stair1 = "mcl_stairs:stair_stonebrickcracked"
|
||||
local stair2 = "mcl_stairs:stair_stonebrickmossy"
|
||||
local stair3 = "mcl_stairs:stair_stone_rough"
|
||||
local stair4 = "mcl_stairs:stair_stonebrick"
|
||||
|
||||
|
||||
local function draw_frame(frame_pos, frame_width, frame_height, orientation, pr, is_chain, rotation)
|
||||
local function draw_frame(frame_pos, frame_width, frame_height, orientation, pr, is_chain, rotation, is_blackstone)
|
||||
local param2 = rotation_to_param2[rotation]
|
||||
local variant = is_blackstone and 2 or 1
|
||||
|
||||
local function set_ruined_node(pos, node)
|
||||
if pr:next(1, 5) == 4 then return end
|
||||
|
@ -68,28 +254,20 @@ local function draw_frame(frame_pos, frame_width, frame_height, orientation, pr,
|
|||
end
|
||||
|
||||
local function get_random_stone_material()
|
||||
local rnd = pr:next(1, 15)
|
||||
if rnd < 4 then return stone1 end
|
||||
if rnd == 4 then return stone2 end
|
||||
if rnd == 5 then return stone3 end
|
||||
return stone4
|
||||
local rnd = pr:next(1, #stone_set_for_frame)
|
||||
return {name = stone_set_for_frame[rnd][variant]}
|
||||
end
|
||||
|
||||
local function get_random_slab()
|
||||
local rnd = pr:next(1, 15)
|
||||
if rnd < 4 then return slab1 end
|
||||
if rnd == 4 then return slab2 end
|
||||
if rnd == 5 then return slab3 end
|
||||
return slab4
|
||||
return {name = slab_set_for_frame[rnd][variant]}
|
||||
end
|
||||
|
||||
local function get_random_stair(param2_offset)
|
||||
local param2 = (param2 + (param2_offset or 0)) % 4
|
||||
local rnd = pr:next(1, 15)
|
||||
if rnd < 4 then return {name = stair1, param2 = param2} end
|
||||
if rnd == 4 then return {name = stair2, param2 = param2} end
|
||||
if rnd == 5 then return {name = stair3, param2 = param2} end
|
||||
return {name = stair4, param2 = param2}
|
||||
local rnd = pr:next(1, #stair_set_for_frame)
|
||||
local stare_name = stair_set_for_frame[rnd][variant]
|
||||
return {name = stare_name, param2 = param2}
|
||||
end
|
||||
|
||||
local function set_frame_stone_material(pos)
|
||||
|
@ -118,7 +296,6 @@ local function draw_frame(frame_pos, frame_width, frame_height, orientation, pr,
|
|||
local air_nodes = frame_nodes - obsidian_nodes
|
||||
|
||||
local function set_frame_node(pos)
|
||||
-- local node_choice = pr:next(1, air_nodes + obsidian_nodes)
|
||||
local node_choice = math_round(mcl_structures_get_perlin_noise_level(pos) * (air_nodes + obsidian_nodes))
|
||||
if node_choice > obsidian_nodes and air_nodes > 0 then
|
||||
air_nodes = air_nodes - 1
|
||||
|
@ -141,7 +318,7 @@ local function draw_frame(frame_pos, frame_width, frame_height, orientation, pr,
|
|||
local is_top_hole = is_top and frame_width > 5 and ((pos2.x == x1 + slide_x * 2 and pos2.z == z1 + slide_z * 2) or (pos2.x == last_x - slide_x * 2 and pos2.z == last_z - slide_z * 2))
|
||||
if is_top_hole then
|
||||
if pr:next(1, 7) > 1 then
|
||||
minetest_swap_node(pos2, {name = "xpanes:bar_flat", param2 = orientation})
|
||||
minetest_swap_node(pos2, {name = PANE_OR_CHAIN_FLAT[variant], param2 = orientation})
|
||||
end
|
||||
else
|
||||
set_frame_stone_material(pos2)
|
||||
|
@ -152,18 +329,18 @@ local function draw_frame(frame_pos, frame_width, frame_height, orientation, pr,
|
|||
local pos = def.pos_outer1
|
||||
local is_decor_here = not is_top and pos.y % 3 == 2
|
||||
if is_decor_here then
|
||||
minetest_swap_node(pos, {name = "mcl_core:stonebrickcarved"})
|
||||
minetest_swap_node(pos, {name = STONE_DECOR[variant]})
|
||||
elseif is_chain then
|
||||
if not is_top and not is_obsidian then
|
||||
minetest_swap_node(pos, {name = "xpanes:bar"})
|
||||
minetest_swap_node(pos, {name = PANE_OR_CHAIN[variant]})
|
||||
else
|
||||
minetest_swap_node(pos, {name = "xpanes:bar_flat", param2 = orientation})
|
||||
minetest_swap_node(pos, {name = PANE_OR_CHAIN_FLAT[variant], param2 = orientation})
|
||||
end
|
||||
else
|
||||
if pr:next(1, 5) == 3 then
|
||||
minetest_swap_node(pos, {name = "mcl_core:stonebrickcracked"})
|
||||
minetest_swap_node(pos, {name = STONE1[variant]})
|
||||
else
|
||||
minetest_swap_node(pos, {name = "mcl_core:stonebrick"})
|
||||
minetest_swap_node(pos, {name = STONE4[variant]})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -253,7 +430,7 @@ local function draw_frame(frame_pos, frame_width, frame_height, orientation, pr,
|
|||
})
|
||||
end end
|
||||
|
||||
local node_top = {name = node_top[pr:next(1, #node_top)]}
|
||||
local node_top = {name = top_decoration_list[pr:next(1, #top_decoration_list)][variant]}
|
||||
if is_chain then
|
||||
set_ruined_frame_stone_material({x = x1 + slide_x * 2, y = last_y + 3, z = z1 + slide_z * 2})
|
||||
set_ruined_frame_stone_material({x = x1 + slide_x , y = last_y + 3, z = z1 + slide_z })
|
||||
|
@ -281,7 +458,9 @@ end
|
|||
|
||||
local possible_rotations = {"0", "90", "180", "270"}
|
||||
|
||||
local function draw_trash(pos, width, height, lift, orientation, pr)
|
||||
local function draw_trash(pos, width, height, lift, orientation, pr, is_blackstone)
|
||||
local variant = is_blackstone and 2 or 1
|
||||
local pos = pos
|
||||
local slide_x = (1 - orientation)
|
||||
local slide_z = orientation
|
||||
local x1 = pos.x - lift - 1
|
||||
|
@ -297,7 +476,7 @@ local function draw_trash(pos, width, height, lift, orientation, pr)
|
|||
for x = x1 + pr:next(0, 2), x2 - pr:next(0, 2) do
|
||||
for z = z1 + pr:next(0, 2), z2 - pr:next(0, 2) do
|
||||
if inverted_opacity_0_5 == 0 or (x % inverted_opacity_0_5 ~= pr:next(0, 1) and z % inverted_opacity_0_5 ~= pr:next(0, 1)) then
|
||||
minetest_swap_node({x = x, y = y, z = z}, {name = node_garbage[pr:next(1, #node_garbage)]})
|
||||
minetest_swap_node({x = x, y = y, z = z}, {name = node_garbage[pr:next(1, #node_garbage)][variant]})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -305,77 +484,6 @@ local function draw_trash(pos, width, height, lift, orientation, pr)
|
|||
end
|
||||
end
|
||||
|
||||
local stair_replacement_list = {
|
||||
"air",
|
||||
"group:water",
|
||||
"group:lava",
|
||||
"group:buildable_to",
|
||||
"group:deco_block",
|
||||
}
|
||||
|
||||
local stair_names = {
|
||||
"mcl_stairs:stair_stonebrickcracked",
|
||||
"mcl_stairs:stair_stonebrickmossy",
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_stone_rough",
|
||||
"mcl_stairs:stair_stonebrick",
|
||||
"mcl_stairs:stair_stonebrick",
|
||||
"mcl_stairs:stair_stonebrick",
|
||||
}
|
||||
local stair_outer_names = {
|
||||
"mcl_stairs:stair_stonebrickcracked_outer",
|
||||
"mcl_stairs:stair_stonebrickmossy_outer",
|
||||
"mcl_stairs:stair_stone_rough_outer",
|
||||
"mcl_stairs:stair_stonebrick_outer",
|
||||
}
|
||||
|
||||
local stair_content = {
|
||||
{name = "mcl_core:lava_source"},
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:stonebrick"},
|
||||
{name = "mcl_nether:magma"},
|
||||
{name = "mcl_nether:netherrack"},
|
||||
{name = "mcl_nether:netherrack"},
|
||||
}
|
||||
|
||||
local stair_content_bottom = {
|
||||
{name = "mcl_nether:magma"},
|
||||
{name = "mcl_nether:magma"},
|
||||
{name = "mcl_nether:netherrack"},
|
||||
{name = "mcl_nether:netherrack"},
|
||||
{name = "mcl_nether:netherrack"},
|
||||
{name = "mcl_nether:netherrack"},
|
||||
}
|
||||
|
||||
local slabs = {
|
||||
{name = "mcl_stairs:slab_stone"},
|
||||
{name = "mcl_stairs:slab_stone"},
|
||||
{name = "mcl_stairs:slab_stone"},
|
||||
{name = "mcl_stairs:slab_stone"},
|
||||
{name = "mcl_stairs:slab_stone"},
|
||||
{name = "mcl_stairs:slab_stonebrick"},
|
||||
{name = "mcl_stairs:slab_stonebrick"},
|
||||
{name = "mcl_stairs:slab_stonebrickcracked"},
|
||||
{name = "mcl_stairs:slab_stonebrickmossy"},
|
||||
}
|
||||
|
||||
local stones = {
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:stone"},
|
||||
{name = "mcl_core:cobble"},
|
||||
{name = "mcl_core:mossycobble"},
|
||||
}
|
||||
|
||||
local stair_selector = {
|
||||
[-1] = {
|
||||
[-1] = {
|
||||
|
@ -383,7 +491,7 @@ local stair_selector = {
|
|||
param2 = 1,
|
||||
},
|
||||
[0] = {
|
||||
names = stair_names,
|
||||
names = stair_set_for_stairs,
|
||||
param2 = 1,
|
||||
},
|
||||
[1] = {
|
||||
|
@ -393,14 +501,14 @@ local stair_selector = {
|
|||
},
|
||||
[0] = {
|
||||
[-1] = {
|
||||
names = stair_names,
|
||||
names = stair_set_for_stairs,
|
||||
param2 = 0,
|
||||
},
|
||||
[0] = {
|
||||
names = stair_content,
|
||||
},
|
||||
[1] = {
|
||||
names = stair_names,
|
||||
names = stair_set_for_stairs,
|
||||
param2 = 2,
|
||||
},
|
||||
},
|
||||
|
@ -410,7 +518,7 @@ local stair_selector = {
|
|||
param2 = 0,
|
||||
},
|
||||
[0] = {
|
||||
names = stair_names,
|
||||
names = stair_set_for_stairs,
|
||||
param2 = 3,
|
||||
},
|
||||
[1] = {
|
||||
|
@ -422,25 +530,14 @@ local stair_selector = {
|
|||
|
||||
local stair_offset_from_bottom = 2
|
||||
|
||||
local function draw_stairs(pos, width, height, lift, orientation, pr, is_chain, param2)
|
||||
|
||||
local function draw_stairs(pos, width, height, lift, orientation, pr, is_chain, param2, is_blackstone)
|
||||
local variant = is_blackstone and 2 or 1
|
||||
local current_stair_content = stair_content
|
||||
local current_stones = stones
|
||||
|
||||
local function set_ruined_node(pos, node)
|
||||
if pr:next(1, 7) < 3 then return end
|
||||
minetest_swap_node(pos, node)
|
||||
return true
|
||||
end
|
||||
|
||||
local param2 = param2
|
||||
local mirror = param2 == 1 or param2 == 2
|
||||
if mirror then
|
||||
param2 = (param2 + 2) % 4
|
||||
end
|
||||
|
||||
if mirror then param2 = (param2 + 2) % 4 end
|
||||
local chain_offset = is_chain and 1 or 0
|
||||
|
||||
local lift = lift + stair_offset_from_bottom
|
||||
local slide_x = (1 - orientation)
|
||||
local slide_z = orientation
|
||||
|
@ -455,52 +552,63 @@ local function draw_stairs(pos, width, height, lift, orientation, pr, is_chain,
|
|||
local y = y2
|
||||
local place_slabs = true
|
||||
local x_key, z_key
|
||||
local need_to_place_chest = true
|
||||
local chest_pos
|
||||
local bad_nodes_ratio = 0
|
||||
while (y >= y1) or (bad_nodes_ratio > 0.07) do
|
||||
local good_nodes_counter = 0
|
||||
for x = x1, x2 do
|
||||
x_key = (x == x1) and -1 or (x == x2) and 1 or 0
|
||||
for z = z1, z2 do
|
||||
local pos = {x = x, y = y, z = z}
|
||||
if #minetest_find_nodes_in_area(pos, pos, stair_replacement_list, false) > 0 then
|
||||
z_key = (z == z1) and -1 or (z == z2) and 1 or 0
|
||||
local stair_coverage = (x_key ~= 0) or (z_key ~= 0)
|
||||
if stair_coverage then
|
||||
if stair_layer then
|
||||
local stair = stair_selector[x_key][z_key]
|
||||
local names = stair.names
|
||||
set_ruined_node(pos, {name = names[pr:next(1, #names)], param2 = stair.param2})
|
||||
elseif place_slabs then
|
||||
set_ruined_node(pos, slabs[pr:next(1, #slabs)])
|
||||
else
|
||||
local placed = set_ruined_node(pos, current_stones[pr:next(1, #current_stones)])
|
||||
if need_to_place_chest and placed then
|
||||
chest_pos = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest_swap_node(chest_pos, {name = "mcl_chests:chest_small"})
|
||||
need_to_place_chest = false
|
||||
end
|
||||
local ruinity = height + lift
|
||||
local y_layer_to_start_squeezing = y1 - 2 * lift
|
||||
while (true) do
|
||||
local x11 = math_round(x1)
|
||||
local x22 = math_round(x2)
|
||||
local z11 = math_round(z1)
|
||||
local z22 = math_round(z2)
|
||||
local good_nodes = minetest_find_nodes_in_area({x = x11, y = y, z = z11}, {x = x22, y = y, z = z22}, stair_replacement_list, false)
|
||||
local good_nodes_ratio = #good_nodes / (x22 - x11 + 1) / (z22 - z11 + 1)
|
||||
if y < y1 and good_nodes_ratio <= 0.07 then return chest_pos end
|
||||
for _, pos in pairs(good_nodes) do
|
||||
if pr:next(1, ruinity) > 1 then
|
||||
local x, z = pos.x, pos.z
|
||||
x_key = (x == x11) and -1 or (x == x22) and 1 or 0
|
||||
z_key = (z == z11) and -1 or (z == z22) and 1 or 0
|
||||
local should_be_a_stair_here = (x_key ~= 0) or (z_key ~= 0)
|
||||
if should_be_a_stair_here then
|
||||
if stair_layer then
|
||||
local stair = stair_selector[x_key][z_key]
|
||||
local names = stair.names
|
||||
minetest_swap_node(pos, {name = names[pr:next(1, #names)][variant], param2 = stair.param2})
|
||||
elseif place_slabs then
|
||||
minetest_swap_node(pos, {name = slabs[pr:next(1, #slabs)][variant]})
|
||||
else
|
||||
minetest_swap_node(pos, {name = current_stones[pr:next(1, #current_stones)][variant]})
|
||||
if not chest_pos then
|
||||
chest_pos = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest_swap_node(chest_pos, {name = "mcl_chests:chest_small"})
|
||||
end
|
||||
elseif not stair_layer then
|
||||
set_ruined_node(pos, current_stair_content[pr:next(1, #current_stair_content)])
|
||||
end
|
||||
else
|
||||
good_nodes_counter = good_nodes_counter + 1
|
||||
elseif not stair_layer then
|
||||
minetest_swap_node(pos, {name = current_stair_content[pr:next(1, #current_stair_content)][variant]})
|
||||
end
|
||||
end
|
||||
end
|
||||
bad_nodes_ratio = 1 - good_nodes_counter / ((x2 - x1 + 1) * (z2 - z1 + 1))
|
||||
if y >= y1 then
|
||||
if y >= y1 - lift then
|
||||
x1 = x1 - 1
|
||||
x2 = x2 + 1
|
||||
z1 = z1 - 1
|
||||
z2 = z2 + 1
|
||||
elseif y < y_layer_to_start_squeezing then
|
||||
local noise = mcl_structures_get_perlin_noise_level(pos) + 0.5
|
||||
x1 = x1 + noise * pr:next(0,2)
|
||||
x2 = x2 - noise * pr:next(0,2)
|
||||
z1 = z1 + noise * pr:next(0,2)
|
||||
z2 = z2 - noise * pr:next(0,2)
|
||||
if x1 >= x2 then return chest_pos end
|
||||
if z1 >= z2 then return chest_pos end
|
||||
elseif y == y_layer_to_start_squeezing then
|
||||
current_stones = stair_content_bottom
|
||||
end
|
||||
if y >= y1 then
|
||||
if (stair_layer or place_slabs) then
|
||||
y = y - 1
|
||||
if y <= y1 then
|
||||
current_stair_content = stair_content_bottom
|
||||
current_stones = stair_content_bottom
|
||||
end
|
||||
end
|
||||
place_slabs = not place_slabs
|
||||
|
@ -508,19 +616,9 @@ local function draw_stairs(pos, width, height, lift, orientation, pr, is_chain,
|
|||
else
|
||||
place_slabs = false
|
||||
y = y - 1
|
||||
local dx1 = pr:next(0, 10)
|
||||
if dx1 < 3 then x1 = x1 + dx1 end
|
||||
local dx2 = pr:next(0, 10)
|
||||
if dx2 < 3 then x2 = x2 - dx1 end
|
||||
if x1 >= x2 then return chest_pos end
|
||||
local dz1 = pr:next(0, 10)
|
||||
if dz1 < 3 then z1 = z1 + dz1 end
|
||||
local dz2 = pr:next(0, 10)
|
||||
if dz2 < 3 then z2 = z2 - dz1 end
|
||||
if z1 >= z2 then return chest_pos end
|
||||
end
|
||||
if ruinity > 2 then ruinity = math.max(ruinity - pr:next(0,2), 2) end
|
||||
end
|
||||
return chest_pos
|
||||
end
|
||||
|
||||
local function enchant(stack, pr)
|
||||
|
@ -533,19 +631,18 @@ local function enchant_armor(stack, pr)
|
|||
mcl_enchanting.enchant_randomly(stack, 30, false, false, false, pr)
|
||||
end
|
||||
|
||||
local function place(pos, rotation, pr)
|
||||
local width = pr:next(2, 10)
|
||||
local height = pr:next(((width < 3) and 3 or 2), 10)
|
||||
local lift = pr:next(0, 4)
|
||||
local rotation = rotation or possible_rotations[pr:next(1, #possible_rotations)]
|
||||
local function common_place(pos, rotation, pr, width, height, lift, is_blackstone)
|
||||
local pos = pos
|
||||
local width = width
|
||||
local height = height
|
||||
local lift = lift
|
||||
local rotation = rotation
|
||||
local orientation = rotation_to_orientation[rotation]
|
||||
assert(orientation)
|
||||
local param2 = rotation_to_param2[rotation]
|
||||
assert(param2)
|
||||
local is_chain = pr:next(1, 3) > 1
|
||||
draw_trash(pos, width, height, lift, orientation, pr)
|
||||
local chest_pos = draw_stairs(pos, width, height, lift, orientation, pr, is_chain, param2)
|
||||
draw_frame({x = pos.x, y = pos.y + lift, z = pos.z}, width + 2, height + 2, orientation, pr, is_chain, rotation)
|
||||
draw_trash(pos, width, height, lift, orientation, pr, is_blackstone)
|
||||
local chest_pos = draw_stairs(pos, width, height, lift, orientation, pr, is_chain, param2, is_blackstone)
|
||||
draw_frame({x = pos.x, y = pos.y + lift, z = pos.z}, width + 2, height + 2, orientation, pr, is_chain, rotation, is_blackstone)
|
||||
if not chest_pos then return end
|
||||
|
||||
local lootitems = mcl_loot.get_loot(
|
||||
|
@ -575,7 +672,7 @@ local function place(pos, rotation, pr)
|
|||
{itemstring = "mcl_clock:clock", weight = 5},
|
||||
{itemstring = "mesecons_pressureplates:pressure_plate_gold_off", weight = 5},
|
||||
{itemstring = "mobs_mc:gold_horse_armor", weight = 5},
|
||||
{itemstring = "mcl_core:goldblock", weight = 1, amount_min = 1, amount_max = 2},
|
||||
{itemstring = TOP_DECOR1, weight = 1, amount_min = 1, amount_max = 2},
|
||||
{itemstring = "mcl_bells:bell", weight = 1},
|
||||
{itemstring = "mcl_core:apple_gold_enchanted", weight = 1},
|
||||
}
|
||||
|
@ -588,6 +685,24 @@ local function place(pos, rotation, pr)
|
|||
mcl_loot.fill_inventory(inv, "main", lootitems, pr)
|
||||
end
|
||||
|
||||
local function place(pos, rotation, pr)
|
||||
local width = pr:next(2, 10)
|
||||
local height = pr:next(((width < 3) and 3 or 2), math.floor((10 + width/2)))
|
||||
local lift = pr:next(0, 2)
|
||||
local rotation = rotation or possible_rotations[pr:next(1, #possible_rotations)]
|
||||
common_place(pos, rotation, pr, width, height, lift, false)
|
||||
minetest.log("action","Ruined portal generated at " .. minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
local function place_blackstone(pos, rotation, pr)
|
||||
local width = pr:next(2, 5)
|
||||
local height = pr:next(((width < 3) and 3 or 2), math.floor((5 + width/2)))
|
||||
local lift = pr:next(0, 1)
|
||||
local rotation = rotation or possible_rotations[pr:next(1, #possible_rotations)]
|
||||
common_place(pos, rotation, pr, width, height, lift, true)
|
||||
minetest.log("action","Ruined portal v2 generated at " .. minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
local function get_place_rank(pos)
|
||||
local x, y, z = pos.x, pos.y, pos.z
|
||||
local p1 = {x = x , y = y, z = z }
|
||||
|
@ -630,3 +745,35 @@ mcl_structures.register_structure({
|
|||
end,
|
||||
place_function = place,
|
||||
})
|
||||
|
||||
mcl_structures.register_structure({
|
||||
name = "ruined_portal_black",
|
||||
decoration = {
|
||||
deco_type = "simple",
|
||||
flags = "all_floors",
|
||||
fill_ratio = scanning_ratio,
|
||||
height = 1,
|
||||
place_on = {"mcl_nether:netherrack", "mcl_nether:soul_sand", "mcl_nether:nether_lava_source", "mcl_core:lava_source"},
|
||||
},
|
||||
on_finished_chunk = function(minp, maxp, seed, vm_context, pos_list)
|
||||
if minp.y > mcl_mapgen.nether.max then return end
|
||||
local pr = PseudoRandom(seed + random_offset)
|
||||
local random_number = pr:next(1, chance_per_chunk)
|
||||
local noise = mcl_structures_get_perlin_noise_level(minp) * noise_multiplier
|
||||
if (random_number + noise) < struct_threshold then return end
|
||||
local pos = pos_list[1]
|
||||
if #pos_list > 1 then
|
||||
local count = get_place_rank(pos)
|
||||
for i = 2, #pos_list do
|
||||
local pos_i = pos_list[i]
|
||||
local count_i = get_place_rank(pos_i)
|
||||
if count_i > count then
|
||||
count = count_i
|
||||
pos = pos_i
|
||||
end
|
||||
end
|
||||
end
|
||||
place_blackstone(pos, nil, pr)
|
||||
end,
|
||||
place_function = place_blackstone,
|
||||
})
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
dofile(modpath .. "/ratelimit.lua")
|
||||
|
||||
local enable_anticheat = true
|
||||
local kick_cheaters = false
|
||||
local kick_threshold = 10
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
-- by LoneWolfHT
|
||||
-- https://github.com/minetest/minetest/issues/12220#issuecomment-1108789409
|
||||
|
||||
local ratelimit = {}
|
||||
local after = minetest.after
|
||||
local LIMIT = 2
|
||||
|
||||
local function remove_entry(ip)
|
||||
ratelimit[ip] = nil
|
||||
end
|
||||
|
||||
minetest.register_on_mods_loaded(function()
|
||||
table.insert(core.registered_on_prejoinplayers, 1, function(player, ip)
|
||||
if ratelimit[ip] then
|
||||
return "You are joining too fast, please try again"
|
||||
else
|
||||
ratelimit[ip] = true
|
||||
after(LIMIT, remove_entry, ip)
|
||||
end
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,154 @@
|
|||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
from pathlib import Path
|
||||
import pprint
|
||||
import time
|
||||
import glob
|
||||
import os
|
||||
|
||||
hostName = "localhost"
|
||||
serverPort = 8080
|
||||
|
||||
paths = {}
|
||||
|
||||
def dump(obj):
|
||||
s = ''
|
||||
for attr in dir(obj):
|
||||
s = s + "obj.%s = %r" % (attr, getattr(obj, attr)) + "\n"
|
||||
return s
|
||||
|
||||
def get_png(path):
|
||||
if path in paths:
|
||||
return Path(pahts[path]).read_bytes()
|
||||
for file in glob.glob("../**/" + path, recursive = True):
|
||||
paths[path] = file
|
||||
return Path(file).read_bytes()
|
||||
return
|
||||
|
||||
def scan():
|
||||
for file in glob.glob("../**/*.png", recursive = True):
|
||||
basename = os.path.basename(file)
|
||||
if basename in paths:
|
||||
print("Duplicate texture name, please fix:\n * %s:\n - %s\n - %s\n" % (basename, paths[basename], file))
|
||||
else:
|
||||
paths[basename] = file
|
||||
|
||||
def color_picker():
|
||||
return """
|
||||
<canvas id="myCanvas" width="256" height="256"></canvas>
|
||||
<br/>
|
||||
<input type='text' size=7 id='color'/>
|
||||
<script>
|
||||
function componentToHex(c) {
|
||||
var hex = c.toString(16);
|
||||
return hex.length == 1 ? "0" + hex : hex;
|
||||
}
|
||||
function function_down(v, d){
|
||||
if (d<=1) {
|
||||
return Math.min(255, Math.floor((1-v) * d * 255))
|
||||
}
|
||||
return 255-Math.min(255, Math.floor(v * (2-d) * 255))
|
||||
}
|
||||
function function_up(v, d){
|
||||
if (d<=1) {
|
||||
return Math.min(255, Math.floor(v * d * 255))
|
||||
}
|
||||
return 255-Math.min(255, Math.floor((1-v) * (2-d) * 255))
|
||||
}
|
||||
function function_keep(v, d){
|
||||
return Math.min(Math.floor(d*255), 255)
|
||||
}
|
||||
function getColorAtXY(x, y){
|
||||
var x0 = (x - 128) / 128;
|
||||
var y0 = (y - 128) / 128;
|
||||
var alpha = 0.5 - Math.atan2(y0, x0) / 2 / Math.PI;
|
||||
var sector_alpha = alpha*3;
|
||||
var sector_number = 2 - Math.floor(sector_alpha);
|
||||
sector_alpha = sector_alpha - Math.floor(sector_alpha);
|
||||
var distance = Math.sqrt(x0 * x0 + y0*y0) * dist_mult;
|
||||
if (sector_number == 0) {
|
||||
return {
|
||||
"r" : function_up(sector_alpha, distance),
|
||||
"b" : function_down(sector_alpha, distance),
|
||||
"g" : function_keep(sector_alpha, distance)
|
||||
};
|
||||
}
|
||||
if (sector_number == 1) {
|
||||
return {
|
||||
"g" : function_up(sector_alpha, distance),
|
||||
"r" : function_down(sector_alpha, distance),
|
||||
"b" : function_keep(sector_alpha, distance)
|
||||
};
|
||||
}
|
||||
return {
|
||||
"b" : function_up(sector_alpha, distance),
|
||||
"g" : function_down(sector_alpha, distance),
|
||||
"r" : function_keep(sector_alpha, distance)
|
||||
};
|
||||
};
|
||||
var canvas = document.getElementById("myCanvas");
|
||||
canvas.addEventListener('mousedown', function(e) {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
const color = getColorAtXY(x, y);
|
||||
const rgb = '#' + componentToHex(color.r) + componentToHex(color.g) + componentToHex(color.b);
|
||||
document.body.style.background = rgb;
|
||||
document.getElementById('color').value = rgb;
|
||||
}, false)
|
||||
var ctx = canvas.getContext("2d");
|
||||
var canvasData = ctx.getImageData(0, 0, 256, 256);
|
||||
var dist_mult = 2 / Math.sqrt(2);
|
||||
var index = 0;
|
||||
for (var y = 0; y < 256; y++) {
|
||||
for (var x = 0; x < 256; x++) {
|
||||
var color = getColorAtXY(x, y);
|
||||
canvasData.data[index++] = color.r;
|
||||
canvasData.data[index++] = color.g;
|
||||
canvasData.data[index++] = color.b;
|
||||
canvasData.data[index++] = 255;
|
||||
}
|
||||
}
|
||||
ctx.putImageData(canvasData, 0, 0)
|
||||
</script>
|
||||
"""
|
||||
|
||||
|
||||
def get_html(path):
|
||||
content = "<p>Request: %s</p>" % path
|
||||
content += "<body>"
|
||||
content += color_picker()
|
||||
content += "<ul>Texture List:"
|
||||
for key, value in paths.items():
|
||||
content += "<li><a href='%s'>%s</a></li>" % (key, key)
|
||||
content += "</ul>"
|
||||
content += "</body></html>"
|
||||
return content
|
||||
|
||||
class MyServer(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
path = self.path
|
||||
if path.endswith(".png"):
|
||||
content = get_png(path)
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "image/png")
|
||||
self.end_headers()
|
||||
self.wfile.write(content)
|
||||
else:
|
||||
content = get_html(path)
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
self.wfile.write(bytes(content, "utf-8"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
scan()
|
||||
webServer = HTTPServer((hostName, serverPort), MyServer)
|
||||
print("Server started http://%s:%s" % (hostName, serverPort))
|
||||
|
||||
try:
|
||||
webServer.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
webServer.server_close()
|
||||
print("Server stopped.")
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
|
||||
TMP_FILE=$(mktemp /tmp/mcl5.XXXXXXXX)
|
||||
|
||||
git --version 2>/dev/null 1>/dev/null
|
||||
IS_GIT_AVAILABLE=$?
|
||||
if [ $IS_GIT_AVAILABLE -ne 0 ]; then
|
||||
echo "Please install git!\n\n"
|
||||
fi
|
||||
|
||||
`git log --pretty="%an" 1>$TMP_FILE 2>/dev/null`
|
||||
IS_GIT_REPO=$?
|
||||
if [ $IS_GIT_REPO -ne 0 ]; then
|
||||
echo "You have to be inside a git repo to update CONTRUBUTOR_LIST.txt\n\n"
|
||||
fi
|
||||
|
||||
# Edit names here:
|
||||
sed -i 's/nikolaus-albinger/Niklp/g' $TMP_FILE
|
||||
|
||||
cat $TMP_FILE | sort | uniq >../mods/HUD/mcl_credits/CONTRUBUTOR_LIST.txt
|
Loading…
Reference in New Issue