Add gearboxes and improve the operation of shafts.
This commit is contained in:
parent
9011835cf4
commit
613b92f541
5 changed files with 125 additions and 96 deletions
|
|
@ -72,8 +72,8 @@ ShaftNetwork = {
|
|||
end,
|
||||
tick = function(e, dtime)
|
||||
local constant_load = math.max(0, math.abs(e.torque.value) -e.load.value) *math.sign(e.torque.value)
|
||||
local net_torque = constant_load -(5 *e.omega)
|
||||
e.alpha = net_torque /e.inertia.value
|
||||
local net_torque = constant_load -(12 *math.sign(e.omega)) -(e.omega)
|
||||
e.alpha = net_torque /math.max(1, e.inertia.value)
|
||||
e.omega = e.omega +(e.alpha *dtime)
|
||||
|
||||
if math.abs(e.omega) < 0.05 then
|
||||
|
|
@ -109,8 +109,11 @@ local function propagate_shaft_update(pos, net, ignore)
|
|||
local e = shaft_networks[old_net][i]
|
||||
if e and e.pos == pos then
|
||||
if not shaft_networks[net] then
|
||||
shaft_networks[net] = ShaftNetwork(net)
|
||||
shaft_networks[net]:read(shaft_networks[old_net]:store())
|
||||
local new_net = ShaftNetwork(net)
|
||||
new_net.alpha = shaft_networks[old_net].alpha
|
||||
new_net.omega = shaft_networks[old_net].omega
|
||||
new_net.angle = shaft_networks[old_net].angle
|
||||
shaft_networks[net] = new_net
|
||||
end
|
||||
e:change_network(net)
|
||||
end
|
||||
|
|
@ -199,7 +202,7 @@ function ns.update_shaft(pos, removing, ignore)
|
|||
for i, x in ipairs(nets) do
|
||||
net = string.format("net_%d_%06d", minetest.get_us_time(), math.random(100000, 999999))
|
||||
-- Provide a different ignore table each time, to ensure that when the same network abuts this node on multiple edges, all touching nodes get the same network in the end.
|
||||
propagate_shaft_update(x, net, {[pos_hash] = true, color = i == 1 and "red" or "blue"})
|
||||
propagate_shaft_update(x, net, {[pos_hash] = true})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -232,7 +235,7 @@ rgt.register_entity("shaft", {
|
|||
shaft_networks[e.net] = ShaftNetwork(e.net)
|
||||
end
|
||||
e:set_angle(shaft_networks[e.net].angle)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 1)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 0.1)
|
||||
table.insert(shaft_networks[e.net], e)
|
||||
end,
|
||||
on_deactivate = function(e)
|
||||
|
|
@ -248,7 +251,6 @@ rgt.register_entity("shaft", {
|
|||
end,
|
||||
|
||||
change_network = function(e, new_net)
|
||||
say("Changed network at "..e.pos:to_string().." from "..e.net.." to "..new_net)
|
||||
local net = shaft_networks[e.net]
|
||||
net.inertia:set(e.pos:to_string(), nil)
|
||||
table.remove(net, table.indexof(net, e))
|
||||
|
|
@ -257,7 +259,7 @@ rgt.register_entity("shaft", {
|
|||
shaft_networks[e.net] = ShaftNetwork(e.net)
|
||||
end
|
||||
table.insert(shaft_networks[e.net], e)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 1)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 0.1)
|
||||
end,
|
||||
set_angle = function(e, angle)
|
||||
-- e.object:set_properties {
|
||||
|
|
@ -291,6 +293,7 @@ rgt.register_node("shaft", {
|
|||
entities = shafts,
|
||||
|
||||
on_place = function(s, p, pt)
|
||||
if rgt.players[p:get_player_name()]:try_rightclick(s, p, pt) then return end
|
||||
local under = minetest.get_node(pt.under)
|
||||
if under.name == "red_glazed_terracotta:shaft" then
|
||||
return minetest.item_place_node(s, p, pt, under.param2)
|
||||
|
|
@ -298,9 +301,9 @@ rgt.register_node("shaft", {
|
|||
|
||||
if not p:get_player_control().sneak then
|
||||
local target = minetest.registered_nodes[under.name].buildable_to and pt.under or pt.above
|
||||
for _, neighbor in ipairs(minetest.find_nodes_in_area(target:offset(-1,-1,-1), target:offset(1,1,1), "shaft")) do
|
||||
for _, neighbor in ipairs(minetest.find_nodes_in_area(target:offset(-1,-1,-1), target:offset(1,1,1), "group:shaft")) do
|
||||
if neighbor:distance(target) <= 1 then
|
||||
return minetest.item_place_node(s, p, pt, minetest.get_node(neighbor).param2)
|
||||
return minetest.item_place_node(s, p, pt, minetest.dir_to_facedir(neighbor:direction(target)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -368,7 +371,7 @@ rgt.register_entity("hand_crank", {
|
|||
shaft_networks[e.net] = ShaftNetwork(e.net)
|
||||
end
|
||||
e:set_angle(shaft_networks[e.net].angle)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 1)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 0.3)
|
||||
table.insert(shaft_networks[e.net], e)
|
||||
end,
|
||||
on_deactivate = function(e)
|
||||
|
|
@ -384,7 +387,14 @@ rgt.register_entity("hand_crank", {
|
|||
end,
|
||||
on_step = function(e, dtime)
|
||||
if not e.cranking then
|
||||
e:set_torque(math.max(0, e.torque -1))
|
||||
e:set_torque(math.max(0, e.torque -30))
|
||||
end
|
||||
|
||||
local net = shaft_networks[e.net]
|
||||
if e.torque *shaft_networks[e.net].omega > 200 then
|
||||
net.torque:set(e.pos:to_string(), 200 /shaft_networks[e.net].omega)
|
||||
else
|
||||
net.torque:set(e.pos:to_string(), e.torque)
|
||||
end
|
||||
end,
|
||||
|
||||
|
|
@ -398,24 +408,22 @@ rgt.register_entity("hand_crank", {
|
|||
shaft_networks[e.net] = ShaftNetwork(e.net)
|
||||
end
|
||||
table.insert(shaft_networks[e.net], e)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 1)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 0.3)
|
||||
shaft_networks[e.net].torque:set(e.pos:to_string(), e.torque)
|
||||
end,
|
||||
add_torque = function(e)
|
||||
e:set_torque(math.min(20, e.torque +1))
|
||||
e:set_torque(math.min(200, e.torque +10))
|
||||
end,
|
||||
set_torque = function(e, torque)
|
||||
if torque ~= e.torque then
|
||||
e.torque = torque
|
||||
local net = shaft_networks[e.net]
|
||||
net.torque:set(e.pos:to_string(), e.torque)
|
||||
end
|
||||
end,
|
||||
set_angle = function(e, angle)
|
||||
-- local net = shaft_networks[e.net]
|
||||
-- e.object:set_properties {
|
||||
-- nametag = string.format("Torque: %s\nLoad: %s\nI: %s\na: %s\nw: %s\nangle: %s", net.torque.value, net.load.value, net.inertia.value, net.alpha, net.omega, net.angle)
|
||||
-- }
|
||||
local net = shaft_networks[e.net]
|
||||
e.object:set_properties {
|
||||
nametag = string.format("Torque: %s\nLoad: %s\nI: %s\na: %s\nw: %s\nangle: %s", net.torque.value, net.load.value, net.inertia.value, net.alpha, net.omega, net.angle)
|
||||
}
|
||||
e.object:set_bone_override("root", {
|
||||
rotation = {
|
||||
vec = vector.new(0, 0, e.invert and angle or -angle),
|
||||
|
|
@ -499,133 +507,143 @@ rgt.register_node("hand_crank", {
|
|||
end
|
||||
})
|
||||
|
||||
local load_testers = {}
|
||||
local gearboxes = {}
|
||||
|
||||
rgt.register_entity("shaft_load_tester", {
|
||||
rgt.register_entity("gearbox", {
|
||||
initial_properties = {
|
||||
visual = "mesh",
|
||||
mesh = "rgt_shaft.gltf",
|
||||
mesh = "rgt_gearbox_shafts.gltf",
|
||||
textures = {"rgt_shaft.png"},
|
||||
pointable = false,
|
||||
pointable = false
|
||||
},
|
||||
on_activate = function(e, data)
|
||||
e.pos = e.object:get_pos():round()
|
||||
|
||||
if load_testers[minetest.hash_node_position(e.pos)] or not minetest.get_node(e.pos).name:find "shaft_load_tester" then
|
||||
if gearboxes[minetest.hash_node_position(e.pos)] or not minetest.get_node(e.object:get_pos()).name:find "gearbox" then
|
||||
e.object:remove()
|
||||
return
|
||||
end
|
||||
extend(e, minetest.deserialize(data or "return {}"))
|
||||
|
||||
e.torque = 0
|
||||
e.omega = 0
|
||||
e.angle = e.angle or 0
|
||||
e.rotation = vector.new(e.rotation.x, e.rotation.y, e.rotation.z)
|
||||
|
||||
e.object:set_armor_groups{immortal = 1}
|
||||
|
||||
e.object:set_rotation(e.rotation)
|
||||
|
||||
e.object:set_bone_override("root", {
|
||||
rotation = {
|
||||
vec = vector.new(0, 0, -e.angle),
|
||||
interpolation = 0,
|
||||
absolute = true
|
||||
}
|
||||
})
|
||||
|
||||
load_testers[minetest.hash_node_position(e.pos)] = e
|
||||
gearboxes[minetest.hash_node_position(e.pos)] = e
|
||||
if not shaft_networks[e.net] then
|
||||
shaft_networks[e.net] = ShaftNetwork(e.net)
|
||||
end
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 2)
|
||||
shaft_networks[e.net].load:set(e.pos:to_string(), 4)
|
||||
e:set_angle(shaft_networks[e.net].angle)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 0.1)
|
||||
table.insert(shaft_networks[e.net], e)
|
||||
end,
|
||||
on_deactivate = function(e)
|
||||
load_testers[minetest.hash_node_position(e.pos)] = nil
|
||||
if not shaft_networks[e.net][1] then
|
||||
gearboxes[minetest.hash_node_position(e.pos)] = nil
|
||||
if not shaft_networks[e.net] then return end
|
||||
table.remove(shaft_networks[e.net], table.indexof(shaft_networks[e.net], e))
|
||||
shaft_networks[e.net]:save()
|
||||
if not shaft_networks[e.net][1] then
|
||||
db:set_string(e.net, minetest.serialize(shaft_networks[e.net]))
|
||||
shaft_networks[e.net] = nil
|
||||
end
|
||||
end,
|
||||
get_staticdata = function(e)
|
||||
return minetest.serialize{rotation = e.rotation, angle = e.angle, net = e.net}
|
||||
return minetest.serialize{rotation = e.rotation, invert1 = e.invert1, invert2 = e.invert2, net = e.net}
|
||||
end,
|
||||
on_step = function(e, dtime)
|
||||
if e.omega == 0 then return end
|
||||
|
||||
minetest.after(0, function()
|
||||
e.angle = (e.angle +(e.omega *dtime)) %(math.pi *2)
|
||||
e.object:set_bone_override("root", {
|
||||
|
||||
change_network = function(e, new_net)
|
||||
local net = shaft_networks[e.net]
|
||||
net.inertia:set(e.pos:to_string(), nil)
|
||||
table.remove(net, table.indexof(net, e))
|
||||
e.net = new_net
|
||||
if not shaft_networks[e.net] then
|
||||
shaft_networks[e.net] = ShaftNetwork(e.net)
|
||||
end
|
||||
table.insert(shaft_networks[e.net], e)
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), 0.1)
|
||||
end,
|
||||
set_angle = function(e, angle)
|
||||
local net = shaft_networks[e.net]
|
||||
-- e.object:set_properties {
|
||||
-- nametag = e.net
|
||||
-- }
|
||||
e.object:set_bone_override("shaft1", {
|
||||
rotation = {
|
||||
vec = vector.new(0, 0, -e.angle),
|
||||
vec = vector.new(0, 0, e.invert1 and angle or -angle),
|
||||
interpolation = 0.1,
|
||||
absolute = true
|
||||
}
|
||||
})
|
||||
e.object:set_bone_override("shaft2", {
|
||||
rotation = {
|
||||
vec = vector.new(e.invert2 and angle or -angle, 0, 0),
|
||||
interpolation = 0.1,
|
||||
absolute = true
|
||||
}
|
||||
})
|
||||
end)
|
||||
end,
|
||||
|
||||
set_angular_velocity = function(e, w)
|
||||
e.omega = w
|
||||
end,
|
||||
})
|
||||
|
||||
rgt.register_node("shaft_load_tester", {
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
rgt.register_node("gearbox", {
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
-0.5, -0.5, 0.5,
|
||||
0.5, 0.5, 6/16
|
||||
{
|
||||
-7/16, -6/16, -7/16,
|
||||
7/16, 6/16, 7/16
|
||||
},
|
||||
{
|
||||
-0.5, -0.5, -0.5,
|
||||
0.5, -6/16, 0.5
|
||||
},
|
||||
{
|
||||
-0.5, 0.5, -0.5,
|
||||
0.5, 6/16, 0.5
|
||||
},
|
||||
}
|
||||
},
|
||||
tiles = {{name = "rgt_spruce_planks.png", align_style = "world"}},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {shaft = 2, dig_immediate = 3},
|
||||
entities = load_testers,
|
||||
entities = gearboxes,
|
||||
|
||||
on_construct = function(pos)
|
||||
local param2 = minetest.get_node(pos).param2
|
||||
local dir = minetest.facedir_to_dir(param2)
|
||||
local angle
|
||||
local rot = rgt.facedir_to_rotation(param2)
|
||||
local right = vector.new(1, 0, 0):rotate(rot)
|
||||
|
||||
local back = minetest.get_node(pos +dir)
|
||||
if back.name:find "shaft" then
|
||||
angle = shafts[minetest.hash_node_position(pos +dir)].angle
|
||||
end
|
||||
|
||||
minetest.add_entity(pos, "red_glazed_terracotta:shaft_load_tester", minetest.serialize{rotation = rgt.facedir_to_rotation(minetest.get_node(pos).param2), angle = angle, invert = dir.z < 0 or dir.z < 0, net = ns.update_shaft(pos)})
|
||||
minetest.add_entity(pos, "red_glazed_terracotta:gearbox", minetest.serialize{rotation = rot, invert1 = dir.x < 0 or dir.y < 0 or dir.z < 0, invert2 = right.x < 0 or right.y < 0 or right.z < 0, net = ns.update_shaft(pos)})
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
load_testers[minetest.hash_node_position(pos)].object:remove()
|
||||
load_testers[minetest.hash_node_position(pos)] = nil
|
||||
local e = gearboxes[minetest.hash_node_position(pos)]
|
||||
shaft_networks[e.net].inertia:set(e.pos:to_string(), nil)
|
||||
e.object:remove()
|
||||
gearboxes[minetest.hash_node_position(pos)] = nil
|
||||
ns.update_shaft(pos)
|
||||
end,
|
||||
on_rightclick = function(pos, node, p, s, pt)
|
||||
local m = rgt.players[p:get_player_name()]
|
||||
if m.cranking then return end
|
||||
m.cranking = minetest.hash_node_position(pos)
|
||||
load_testers[m.cranking].cranking = true
|
||||
m:listen("tick", do_crank)
|
||||
end,
|
||||
|
||||
_network_can_accept = function(pos, from, param2)
|
||||
local dir = minetest.facedir_to_dir(param2)
|
||||
local rot = rgt.facedir_to_rotation(param2)
|
||||
local dir = from:direction(pos)
|
||||
|
||||
return dir == pos:direction(from)
|
||||
return dir == vector.new(0, 0, 1):rotate(rot) or
|
||||
dir == vector.new(0, 0, -1):rotate(rot) or
|
||||
dir == vector.new(1, 0, 0):rotate(rot) or
|
||||
dir == vector.new(-1, 0, 0):rotate(rot)
|
||||
end,
|
||||
_network_neighbors = function(pos, param2)
|
||||
local param2 = minetest.get_node(pos).param2
|
||||
local dir = minetest.facedir_to_dir(param2)
|
||||
local angle
|
||||
local rot = rgt.facedir_to_rotation(param2)
|
||||
|
||||
local back = minetest.get_node_raw(pos.x +dir.x, pos.y +dir.y, pos.z +dir.z)
|
||||
if minetest.get_item_group(rgt.content_ids_to_nodes[back], "shaft") > 0 then
|
||||
return {pos +dir}
|
||||
end
|
||||
return {}
|
||||
return {
|
||||
pos +vector.new(0, 0, 1):rotate(rot),
|
||||
pos +vector.new(0, 0, -1):rotate(rot),
|
||||
pos +vector.new(1, 0, 0):rotate(rot),
|
||||
pos +vector.new(-1, 0, 0):rotate(rot)
|
||||
}
|
||||
end
|
||||
})
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -426,6 +426,15 @@ Player = {
|
|||
p:hud_set_hotbar_image("[combine:"..(21 *slots +1).."x22"..list)
|
||||
p:hud_set_hotbar_selected_image("rgt_hotbar_selected.png")
|
||||
end,
|
||||
try_rightclick = function(m, s, p, pt)
|
||||
if m.pointed_node and m.pointed_node.node_under then
|
||||
local rc = minetest.registered_nodes[m.pointed_node.node_under.name].on_rightclick
|
||||
if rc then
|
||||
rc(m.pointed_node.under, m.pointed_node.node_under, p, s, pt)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
deinit = function(m)
|
||||
m:dispatch("deinit")
|
||||
m.health_display:remove()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ function ns.add_point(point, args)
|
|||
min = vector.new(-1,-1,-1),
|
||||
max = vector.new(1,1,1)
|
||||
},
|
||||
texture = args and args.color and "[fill:1x1:0,0:"..args.color or args.texture or "[fill:1x1:0,0:#faa",
|
||||
texture = args and args.color and "[fill:1x1:0,0:"..args.color or args and args.texture or "[fill:1x1:0,0:#faa",
|
||||
time = 10,
|
||||
amount = 50,
|
||||
size = 5
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue