add gates_long and xconnected mods

master
elite 2017-07-05 18:31:01 -04:00
parent 225ce91838
commit 294415a879
7 changed files with 586 additions and 0 deletions

View File

@ -0,0 +1,14 @@
This is a mod for Minetest.
It adds gates that fit well to fences and xconnected nodes.
The passageway through the fence gate is not as slim as with other, existing
mods. Mobs from TenPlus1' version of simple mobs cannot jump over the
closed gate. They can walk through the open gate of course. In order to
keep cattle loss at a minimum, the gate will auto-close using an abm after
about 5 seconds.
Variants for all wood types from default are included, including default:tree.
Crafting:
steel ingot - wood (or tree) - steel ingot
(nothing) - wood (or tree) - (nothing)

View File

@ -0,0 +1 @@
default

View File

@ -0,0 +1,135 @@
gates_long = {}
gates_long.register_gate = function( type_name, desc, tiles, craft_from)
-- the closed version contains the string "fence" in its name - thus preventing mobs from jumping over
minetest.register_node("gates_long:fence_gate_closed_"..type_name, {
description = desc.." fence gate (closed)",
drawtype = "nodebox",
-- top, bottom, side1, side2, inner, outer
tiles = tiles,
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
node_box = {
type = "fixed",
fixed = {
-- horizontal wood
{ -0.85, -0.25, -0.02, -0.005, -0.05, 0.02},
{ -0.85, 0.15, -0.02, -0.005, 0.35, 0.02},
{ 0.005, -0.25, -0.02, 0.85, -0.05, 0.02},
{ 0.005, 0.15, -0.02, 0.85, 0.35, 0.02},
-- vertical wood
{ -0.80, -0.05, -0.02, -0.60, 0.15, 0.02},
{ 0.60, -0.05, -0.02, 0.80, 0.15, 0.02},
{ -0.25, -0.05, -0.02, -0.05, 0.15, 0.02},
{ 0.05, -0.05, -0.02, 0.25, 0.15, 0.02},
-- locking mechanism (top)
{ -0.15, 0.32, -0.01, 0.15, 0.38, 0.01},
-- locking mechanism (bottom)
{ -0.15, -0.28, -0.01, 0.15, -0.22, 0.01},
-- hinges for the horizontal wood
{ -0.91, -0.24, -0.015, -0.84, -0.06, 0.015},
{ -0.91, 0.16, -0.015, -0.84, 0.34, 0.015},
{ 0.84, -0.24, -0.015, 0.91, -0.06, 0.015},
{ 0.84, 0.16, -0.015, 0.91, 0.34, 0.015},
},
},
selection_box = {
type = "fixed",
fixed = {
{ -0.85, -0.25, -0.1, 0.85, 0.35, 0.1},
},
},
on_rightclick = function(pos, node, puncher)
minetest.swap_node(pos, {name = "gates_long:gate_open_"..type_name, param2 = node.param2})
end,
is_ground_content = false,
})
-- the opened version allows cattle to pass (until it autocloses)
minetest.register_node("gates_long:gate_open_"..type_name, {
description = desc.." fence gate (open)",
drawtype = "nodebox",
-- top, bottom, side1, side2, inner, outer
tiles = tiles,
paramtype = "light",
paramtype2 = "facedir",
drop = "gates_long:fence_gate_closed_"..type_name,
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1},
node_box = {
type = "fixed",
fixed = {
-- horizontal wood
{ -0.87, -0.25, -0.02, -0.83, -0.05, 0.85},
{ -0.87, 0.15, -0.02, -0.83, 0.35, 0.85},
{ 0.83, -0.25, -0.02, 0.87, -0.05, 0.85},
{ 0.83, 0.15, -0.02, 0.87, 0.35, 0.85},
-- vertical wood
{ -0.87, -0.05, 0.80, -0.83, 0.15, 0.60},
{ -0.87, -0.05, 0.25, -0.83, 0.15, 0.05},
{ 0.83, -0.05, 0.80, 0.87, 0.15, 0.60},
{ 0.83, -0.05, 0.25, 0.87, 0.15, 0.05},
-- locking mechanism (top) - they are only on one side
{ -0.86, 0.32, 0.53, -0.84, 0.38, 0.83},
-- locking mechanism (bottom) - these as well
{ -0.86, -0.28, 0.53, -0.84, -0.22, 0.83},
-- hinges for the horizontal wood (they remain the same)
{ -0.91, -0.24, -0.015, -0.84, -0.06, 0.015},
{ -0.91, 0.16, -0.015, -0.84, 0.34, 0.015},
{ 0.84, -0.24, -0.015, 0.91, -0.06, 0.015},
{ 0.84, 0.16, -0.015, 0.91, 0.34, 0.015},
},
},
selection_box = {
type = "fixed",
fixed = {
{ -0.90, -0.25, 0, 0.90, 0.35, 0.50},
},
},
on_rightclick = function(pos, node, puncher)
minetest.swap_node(pos, {name = "gates_long:fence_gate_closed_"..type_name, param2 = node.param2})
end,
is_ground_content = false,
})
-- automaticly close the gates again to prevent cattle from escaping
minetest.register_abm({
nodenames = {"gates_long:gate_open_"..type_name},
interval = 5,
chance = 1,
action = function(pos, old_node)
minetest.swap_node(pos, {name = "gates_long:fence_gate_closed_"..type_name, param2 = old_node.param2})
end
})
minetest.register_craft({
output = "gates_long:fence_gate_closed_"..type_name.." 2",
recipe = {
{ "default:steel_ingot", craft_from, "default:steel_ingot" },
{ "", craft_from, "" },
}
})
end
gates_long.register_gate( 'wood', 'wooden', {'default_wood.png'}, "default:wood" )
gates_long.register_gate( 'junglewood','junglewood',{'default_junglewood.png'}, "default:junglewood" )
gates_long.register_gate( 'pine', 'pine', {'default_pine_wood.png'}, "default:pine_wood" )
gates_long.register_gate( 'acacia', 'acacia', {'default_acacia_wood.png'}, "default:acacia_wood" )
gates_long.register_gate( 'tree', 'tree', {'default_tree.png^[transformR90'}, "default:tree" )

View File

@ -0,0 +1,14 @@
Replacement for xpanes. Uses less nodes.
Currently adds a huge variety of nodes; there ought to be a better,
more limited selection in the future.
For more information and discussion, see
[the forum thread](https://forum.minetest.net/viewtopic.php?f=9&t=12882)
for this mod.
You might also be intrested in
[gates_long](https://github.com/Sokomine/gates_long)
For more information, see
[this forum thread](https://forum.minetest.net/viewtopic.php?f=9&t=13189&p=190683)
License: GPLv3

View File

@ -0,0 +1,2 @@
default
stained_glass?

View File

@ -0,0 +1,48 @@
-----------------------------------------------------------------------
-- xconnected.lua contains the actual code and api for xconnected nodes
-----------------------------------------------------------------------
dofile(minetest.get_modpath("xconnected").."/xconnected.lua");
-----------------------------------------------------------------------
-- register some example panes, walls and fences
-----------------------------------------------------------------------
-- for comparison: xpanes
xconnected.register_pane( 'xconnected:pane_glass', 'default_glass.png', 'default:glass');
xconnected.register_pane( 'xconnected:pane_obsidian_glass', 'default_obsidian_glass.png', 'default:obsidian_glass');
-- diffrent types of walls
xconnected.register_wall( 'xconnected:wall_tree', 'default_tree.png', 'default:tree' );
xconnected.register_wall( 'xconnected:wall_wood', 'default_wood.png', 'default:fence_wood' );
xconnected.register_wall( 'xconnected:wall_stone', 'default_stone.png', 'default:stone' );
xconnected.register_wall( 'xconnected:wall_cobble', 'default_cobble.png', 'default:cobble' );
xconnected.register_wall( 'xconnected:wall_brick', 'default_brick.png', 'default:brick' );
xconnected.register_wall( 'xconnected:wall_stone_brick', 'default_stone_brick.png', 'default:stonebrick' );
xconnected.register_wall( 'xconnected:wall_sandstone_brick', 'default_sandstone_brick.png', 'default:sandstonebrick' );
xconnected.register_wall( 'xconnected:wall_desert_stone_brick', 'default_desert_stone_brick.png', 'default:desert_stonebrick' );
xconnected.register_wall( 'xconnected:wall_obsidian_brick', 'default_obsidian_brick.png', 'default:obsidianbrick' );
xconnected.register_wall( 'xconnected:wall_hedge', 'default_leaves.png', 'default:leaves' );
xconnected.register_wall( 'xconnected:wall_clay', 'default_clay.png', 'default:clay' );
xconnected.register_wall( 'xconnected:wall_coal_block', 'default_coal_block.png', 'default:coalblock' );
-- xfences can also be emulated
xconnected.register_fence('xconnected:fence', 'default_wood.png', 'default:wood');
xconnected.register_fence('xconnected:fence_pine', 'default_pine_wood.png', 'default:pine_wood');
xconnected.register_fence('xconnected:fence_jungle', 'default_junglewood.png', 'default:junglewood');
xconnected.register_fence('xconnected:fence_acacia', 'default_acacia_wood.png', 'default:acacia_wood');
--[[
-- this innocent loop creates quite a lot of nodes - but only if you have the stained_glass mod installed
if( minetest.get_modpath( "stained_glass" )
and minetest.global_exists( stained_glass_hues)
and minetest.global_exists( stained_glass_shade)) then
for _,hue in ipairs( stained_glass_hues ) do
for _,shade in ipairs( stained_glass_shade ) do
xconnected.register_pane( 'xconnected:pane_'..shade[1]..hue[1], 'stained_glass_'..shade[1]..hue[1]..'.png');
end
end
end
--]]

View File

@ -0,0 +1,372 @@
xconnected = {}
-- change the drops value if you want the player to get one of the other node types when digged (i.e. c0 or ln or lp)
local drops = "c4";
-- this table contains the new postfix and param2 for a newly placed node
-- depending on its neighbours
local xconnected_get_candidate = {};
-- no neighbours
xconnected_get_candidate[0] = {"_c0", 0 };
-- exactly one neighbour
xconnected_get_candidate[1] = {"_c1", 1 };
xconnected_get_candidate[2] = {"_c1", 0 };
xconnected_get_candidate[4] = {"_c1", 3 };
xconnected_get_candidate[8] = {"_c1", 2 };
-- a line between two nodes
xconnected_get_candidate[5] = {"_ln", 1 };
xconnected_get_candidate[10] = {"_ln", 0 };
-- two neighbours
xconnected_get_candidate[3] = {"_c2", 0 };
xconnected_get_candidate[6] = {"_c2", 3 };
xconnected_get_candidate[12] = {"_c2", 2 };
xconnected_get_candidate[9] = {"_c2", 1 };
-- three neighbours
xconnected_get_candidate[7] = {"_c3", 3 };
xconnected_get_candidate[11] = {"_c3", 0 };
xconnected_get_candidate[13] = {"_c3", 1 };
xconnected_get_candidate[14] = {"_c3", 2 };
-- four neighbours
xconnected_get_candidate[15] = {"_c4", 1 };
local directions = {
{x = 1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = -1, y = 0, z = 0},
{x = 0, y = 0, z = -1},
}
-- this function is called when a middle node (connected to two other ones on opposing sides)
-- is punched with a normal node of that type (the _c4 variant)
xconnected.on_punch = function( pos, node, puncher, pointed_thing )
if( not( puncher ) or not( puncher:get_wielded_item() )) then
return;
end
local wielded = puncher:get_wielded_item():get_name();
if( not( wielded )
or wielded == ""
or not( node )
or not( node.name )
or not( minetest.registered_items[ wielded ] )
or not( minetest.registered_items[ node.name ] )) then
return;
end
-- if the node is a middle one, swap between the version with a middle post and without
local base_name = string.sub( wielded, 1, string.len( wielded )-3 );
if( node.name == base_name.."_ln" ) then
minetest.swap_node( pos, {name=base_name.."_lp", param2=node.param2});
elseif( node.name == base_name.."_lp" ) then
minetest.swap_node( pos, {name=base_name.."_ln", param2=node.param2});
end
end
-- each node depends on the position and amount of neighbours of the same type;
-- the param2 value of the neighbour is not important here
xconnected_update_one_node = function( pos, name, digged )
if( not( pos ) or not( name) or not( minetest.registered_nodes[name])) then
return;
end
local candidates = {0,0,0,0};
local id = 0;
local pow2 = {1,2,4,8};
for i, dir in pairs(directions) do
local node = minetest.get_node( {x=pos.x+dir.x, y=pos.y, z=pos.z+dir.z });
if( node
and node.name
and minetest.registered_nodes[node.name] ) then
local ndef= minetest.registered_nodes[node.name];
-- nodes that drop the same are considered similar xconnected nodes
if( ndef.drop == name
-- ..and also those that share the xcentered group
or (ndef.groups and ndef.groups.xconnected)) then
candidates[i] = node.name;
id = id+pow2[i];
end
-- connect to other solid nodes as well
if( ndef.walkable ~= false
and ndef.drawtype ~= "nodebox") then
-- this neighbour does not need updating
candidates[i] = 0;
-- ..but is relevant as far as selecting our shape goes
id = id+pow2[i];
end
end
end
if( digged ) then
return candidates;
end
local new_node = xconnected_get_candidate[ id ];
if( new_node and new_node[1] ) then
local new_name = string.sub( name, 1, string.len( name )-3 )..new_node[1];
if( new_name and minetest.registered_nodes[ new_name ]) then
minetest.swap_node( pos, {name=new_name, param2=new_node[2] });
-- if no central node without neighbours is defined, take the c4 variant
elseif( new_node[1]=='_c0' and not( minetest.registered_nodes[ new_name ])) then
minetest.swap_node( pos, {name=name, param2=0 });
end
end
return candidates;
end
-- called in on_construct and after_dig_node
xconnected_update = function( pos, name, active, has_been_digged )
if( not( pos ) or not( name) or not( minetest.registered_nodes[name])) then
return;
end
local c = xconnected_update_one_node( pos, name, has_been_digged );
for j,dir2 in pairs(directions) do
if( c[j]~=0 and c[j]~='ignore') then
xconnected_update_one_node( {x=pos.x+dir2.x, y=pos.y, z=pos.z+dir2.z}, c[j], false );
end
end
end
-- def: that part of the node definition that is shared between all nodes
-- node_box_data: has to be a table that contains defs for "c0", "c1", "c2", "c3", "c4", "ln" (optionally "lp")
-- c<nr>: node is connected to that many neighbours clockwise
-- ln: node has 2 neighbours at opposite ends and forms a line with them
xconnected.register = function( name, def, node_box_data, selection_box_data, craft_from )
for k,v in pairs( node_box_data ) do
-- some common values for all xconnected nodes
def.drawtype = "nodebox";
def.paramtype = "light";
def.paramtype2 = "facedir";
-- similar xconnected nodes are identified by having the same drop
def.drop = name.."_"..drops; -- default: "_c4";
-- nodebox and selection box have been calculated using smmyetry
def.node_box = {
type = "fixed",
fixed = node_box_data[k],
};
def.selection_box = {
type = "fixed",
fixed = selection_box_data[k],
};
if( not( def.tiles )) then
def.tiles = def.textures;
end
-- nodes of the xconnected type all share one group and connect to each other
if( not( def.groups )) then
def.groups = {xconnected=1,oddly_breakable_by_hand=1,choppy=1};
else
def.groups.xconnected = 1;
end
local new_def = minetest.deserialize( minetest.serialize( def ));
if( k==drops ) then
-- update nodes when needed
new_def.on_construct = function( pos )
return xconnected_update( pos, name.."_"..drops, true, nil );
end
else
-- avoid spam in creative inventory
new_def.groups.not_in_creative_inventory = 1;
end
-- update neighbours when this node is dug
new_def.after_dig_node = function(pos, oldnode, oldmetadata, digger)
return xconnected_update( pos, name.."_"..drops, true, true );
end
-- punching is used to swap nodes of type _ln and _lp
if( k=='ln' or k=='lp' ) then
new_def.on_punch = xconnected.on_punch;
end
-- actually register the node
minetest.register_node( name.."_"..k, new_def );
end
if( craft_from ) then
minetest.register_craft({
output = name.."_"..drops.." 6",
recipe = {
{craft_from, craft_from, craft_from},
{craft_from, craft_from, craft_from}
}
})
end
end
-- make use of the symmetry of the nodes and calculate the nodeboxes that way
-- (may also be used for collusion boxes);
-- the center_node_box_list is shared by all nodes that have nighbours
xconnected.construct_node_box_data = function( node_box_list, center_node_box_list, node_box_line )
local res = {};
res.c1 = {};
res.c2 = {};
res.c3 = {};
res.c4 = {};
-- start with the node that is only connected to one neighbour
for _,v in pairs( node_box_list ) do
-- the node c1 already contains all nodes rotated the right way
table.insert( res.c1, v );
table.insert( res.c2, v );
table.insert( res.c3, v );
table.insert( res.c4, v );
end
-- this node is connected to two neighbours and forms a curve/corner;
-- it keeps the nodes from above plus..
for _,v in pairs( node_box_list ) do
-- swap x and z - we are working on a corner node
table.insert( res.c2, {v[3], v[2], v[1], v[6], v[5], v[4]});
table.insert( res.c3, {v[3], v[2], v[1], v[6], v[5], v[4]});
table.insert( res.c4, {v[3], v[2], v[1], v[6], v[5], v[4]});
end
-- now we have a t-crossing
for _,v in pairs( node_box_list ) do
-- mirror x
table.insert( res.c3, {v[4], v[2], v[3]-0.5, v[1], v[5], v[6]-0.5});
table.insert( res.c4, {v[4], v[2], v[3]-0.5, v[1], v[5], v[6]-0.5});
end
-- ...and now a node which is connected to four neighbours
for _,v in pairs( node_box_list ) do
-- swap x and z and mirror
table.insert( res.c4, {v[3]-0.5, v[2], v[4], v[6]-0.5, v[5], v[1]});
end
res.c0 = {};
for _,v in pairs( center_node_box_list ) do
table.insert( res.c0, v );
table.insert( res.c1, v );
table.insert( res.c2, v );
table.insert( res.c3, v );
table.insert( res.c4, v );
end
-- no center node
if( #res.c0 < 1 ) then
res.c0 = nil;
end
res.ln = node_box_line;
res.lp = {}; -- like ln, but with a middle post
for _,v in pairs( node_box_line ) do
table.insert( res.lp, v );
end
for _,v in pairs( center_node_box_list ) do
table.insert( res.lp, v );
end
return res;
end
-- emulate xpanes
xconnected.register_pane = function( name, tiles, craft_from, def )
local node_box_data = xconnected.construct_node_box_data(
-- a half-pane
{{-1/32, -0.5, 0, 1/32, 0.5, 0.5}},
-- there is nothing special in the center
{},
-- a full pane (with neighbours on opposite sides)
{{-1/32, -0.5, -0.5, 1/32, 0.5, 0.5}});
local selection_box_data =
xconnected.construct_node_box_data(
{{-0.06, -0.5, 0, 0.06, 0.5, 0.5}},
{},
{{-0.06, -0.5, -0.5, 0.06, 0.5, 0.5}});
if( not( def )) then
def = {
description = name.." Pane",
textures = {tiles,tiles,tiles,tiles},
is_ground_content = false,
sunlight_propagates = true,
use_texture_alpha = true,
sounds = default.node_sound_glass_defaults(),
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
};
end
xconnected.register( name,
def,
-- node boxes (last one: full one)
node_box_data,
-- selection boxes (last one: full one)
selection_box_data,
craft_from
);
end
xconnected.register_wall = function( name, tiles, craft_from, def )
local node_box_data = xconnected.construct_node_box_data(
-- one extension
-- {{-3/16, -0.5, 0, 3/16, 5/16, 0.5}},
{{-3/16, -0.5-(3/16), 0, 3/16, 5/16, 0.5}},
-- the central part
{{-4/16, -0.5, -4/16, 4/16, 0.5, 4/16 },
{ -3/16, -0.5-(3/16), -3/16, 3/16, -0.5, 3/16 }},
-- neighbours on two opposide sides
-- {{-3/16, -0.5, -0.5, 3/16, 5/16, 0.5}});
{{-3/16, -0.5-(3/16), -0.5, 3/16, 5/16, 0.5}});
local selection_box_data =
xconnected.construct_node_box_data(
{{-0.2, -0.5, 0, 0.2, 5/16, 0.5}},
{{-0.25, -0.5, -0.25, 0.25, 0.5, 0.25 }},
{{-0.2, -0.5, -0.5, 0.2, 5/16, 0.5}});
if( not( def )) then
def = {
description = name.." Wall",
textures = {tiles,tiles,tiles,tiles},
is_ground_content = false,
sunlight_propagates = true,
sounds = default.node_sound_stone_defaults(),
groups = {cracky=3, stone=1, pane=1},
};
end
xconnected.register( name,
def,
node_box_data,
selection_box_data,
craft_from
);
end
xconnected.register_fence = function( name, tiles, craft_from, def )
local node_box_data = xconnected.construct_node_box_data(
-- one extension
{{-0.06, 0.25, 0, 0.06, 0.4, 0.5},
{-0.06, -0.15, 0, 0.06, 0, 0.5}},
-- the central part
-- {{-0.1, -0.5, -0.1, 0.1, 0.5, 0.1}},
{{-0.1, -0.5-(3/16), -0.1, 0.1, 0.5, 0.1}},
-- neighbours on two opposide sides
{{-0.06, 0.25, -0.5, 0.06, 0.4, 0.5},
{-0.06, -0.15, -0.5, 0.06, 0, 0.5}});
-- only the central part acts as a selection box
local selection_box_data = xconnected.construct_node_box_data(
{},
{{-0.2, -0.5, -0.2, 0.2, 0.5, 0.2}},
{{-0.2, -0.5, -0.2, 0.2, 0.5, 0.2}});
if( not( def )) then
def = {
description = name.." Wall",
textures = {tiles,tiles,tiles,tiles},
is_ground_content = false,
sunlight_propagates = true,
sounds = default.node_sound_stone_defaults(),
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=2, pane=1, flammable=2},
};
end
xconnected.register( name,
def,
node_box_data,
selection_box_data,
craft_from
);
end