From 9011835cf44a6169b9f6e4d4eac49cfbaf9b4999 Mon Sep 17 00:00:00 2001 From: Signal Date: Sat, 9 May 2026 16:01:10 -0400 Subject: [PATCH] Cranks, shafts, and spruce trees. --- mods/rgt_base/init.lua | 117 +++- mods/rgt_cosmetics/init.lua | 2 +- mods/rgt_hud/init.lua | 26 + mods/rgt_inv/init.lua | 11 +- mods/rgt_machines/rgt_machines/init.lua | 100 +++ .../rgt_machines_electric/init.lua | 2 +- .../rgt_machines_mechanical/init.lua | 635 +++++++++++++++++- .../models/rgt_hand_crank.gltf | 1 + .../models/rgt_shaft.gltf | 1 + .../textures/rgt_hand_crank.png | Bin 0 -> 820 bytes .../textures/rgt_shaft.png | Bin 0 -> 634 bytes .../textures/rgt_iron_plating.png | Bin 0 -> 278 bytes mods/rgt_player/init.lua | 15 +- mods/rgt_player/textures/object_crosshair.png | Bin 117 -> 147 bytes mods/rgt_things/modpack.conf | 0 mods/rgt_things/rgt_lights/init.lua | 92 +++ mods/rgt_things/rgt_lights/mod.conf | 2 + .../rgt_lights/models/rgt_lantern.gltf | 1 + .../models/rgt_lantern_hanging.gltf | 1 + .../textures/rgt_lantern_copper.png | Bin 0 -> 413 bytes .../rgt_lights/textures/rgt_lantern_iron.png | Bin 0 -> 403 bytes mods/rgt_towns/rgt_towns_core/visuals.lua | 2 +- mods/rgt_vehicles/rgt_vehicles/init.lua | 0 mods/rgt_vehicles/rgt_vehicles/mod.conf | 2 + mods/rgt_world/init.lua | 108 +-- mods/rgt_world/textures/rgt_acacia_planks.png | Bin 272 -> 320 bytes mods/rgt_world/textures/rgt_basalt.png | Bin 217 -> 214 bytes .../textures/rgt_basalt_brick_large.png | Bin 0 -> 291 bytes mods/rgt_world/textures/rgt_basalt_tile.png | Bin 0 -> 257 bytes mods/rgt_world/textures/rgt_birch_planks.png | Bin 277 -> 316 bytes mods/rgt_world/textures/rgt_dark_planks.png | Bin 263 -> 293 bytes mods/rgt_world/textures/rgt_oak_planks.png | Bin 272 -> 313 bytes .../textures/rgt_polished_basalt_tile.png | Bin 0 -> 199 bytes .../rgt_world/textures/rgt_redwood_planks.png | Bin 272 -> 306 bytes mods/rgt_world/textures/rgt_spruce_leaves.png | Bin 0 -> 372 bytes .../textures/rgt_spruce_log_side.png | Bin 0 -> 373 bytes .../rgt_world/textures/rgt_spruce_log_top.png | Bin 0 -> 420 bytes mods/rgt_world/textures/rgt_spruce_planks.png | Bin 270 -> 306 bytes mods/rgt_world/variants.lua | 132 +++- mods/rgt_world/wood.lua | 350 ++++++++++ 40 files changed, 1496 insertions(+), 104 deletions(-) create mode 100644 mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_hand_crank.gltf create mode 100644 mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_shaft.gltf create mode 100644 mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/textures/rgt_hand_crank.png create mode 100644 mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/textures/rgt_shaft.png create mode 100644 mods/rgt_materials/textures/rgt_iron_plating.png create mode 100644 mods/rgt_things/modpack.conf create mode 100644 mods/rgt_things/rgt_lights/init.lua create mode 100644 mods/rgt_things/rgt_lights/mod.conf create mode 100644 mods/rgt_things/rgt_lights/models/rgt_lantern.gltf create mode 100644 mods/rgt_things/rgt_lights/models/rgt_lantern_hanging.gltf create mode 100644 mods/rgt_things/rgt_lights/textures/rgt_lantern_copper.png create mode 100644 mods/rgt_things/rgt_lights/textures/rgt_lantern_iron.png create mode 100644 mods/rgt_vehicles/rgt_vehicles/init.lua create mode 100644 mods/rgt_vehicles/rgt_vehicles/mod.conf create mode 100644 mods/rgt_world/textures/rgt_basalt_brick_large.png create mode 100644 mods/rgt_world/textures/rgt_basalt_tile.png create mode 100644 mods/rgt_world/textures/rgt_polished_basalt_tile.png create mode 100644 mods/rgt_world/textures/rgt_spruce_leaves.png create mode 100644 mods/rgt_world/textures/rgt_spruce_log_side.png create mode 100644 mods/rgt_world/textures/rgt_spruce_log_top.png create mode 100644 mods/rgt_world/wood.lua diff --git a/mods/rgt_base/init.lua b/mods/rgt_base/init.lua index 2732c5c..e5d130e 100644 --- a/mods/rgt_base/init.lua +++ b/mods/rgt_base/init.lua @@ -9,6 +9,8 @@ function extend(dst, src) return dst end +table.merge = extend + -- PHP-style helper verb function include(file) return dofile(minetest.get_modpath(minetest.get_current_modname()).."/"..file) @@ -59,7 +61,7 @@ EventTarget = { local l = e.listeners[channel] if not l then return end for i = 1, #l do - l[i](...) + if l[i] then l[i](...) end end end } @@ -70,15 +72,22 @@ setmetatable(EventTarget, { StateMachine = { init = function(obj, states) local super = EventTarget() - local e = { + local e = table.merge(super, { states = states, active_states = {}, obj = obj - } - return setmetatable(e, {__index = super}) + }) + return setmetatable(e, {__index = StateMachine}) end, add_state = function(e, state) if e.active_states[state] then return false end + if e.states[state].excludes then + for i = 1, #e.states[state].excludes do + if e.active_states[e.states[state].excludes[i]] then + e:remove_state(e.states[state].excludes[i]) + end + end + end e.states[state]:add(e.obj) e.active_states[state] = true return true @@ -100,6 +109,40 @@ setmetatable(StateMachine, { __index = EventTarget() }) +ModifierStack = { + init = function(mode) + local e = EventTarget() + extend(e, { + mode = mode or "add", + value = 0 + }) + return setmetatable(e, {__index = ModifierStack}) + end, + set = function(e, key, value) + if key == "value" then return end + if e[key] then + if e.mode == "multiply" then + e.value = e.value /e[key] + else + e.value = e.value -e[key] + end + end + e[key] = value + if e[key] then + if e.mode == "multiply" then + e.value = e.value *e[key] + else + e.value = e.value +e[key] + end + end + e:dispatch("change") + end, +} +setmetatable(ModifierStack, { + __call = function(_, ...) return ModifierStack.init(...) end, + __index = EventTarget +}) + rgt = { adjacent_neighbor_offests = { vector.new(0,0,1), @@ -117,6 +160,14 @@ rgt = { vector.new(1,0,0), vector.new(-1,0,0), }, + abutting_neighbor_offests = { + vector.new(0,0,1), + vector.new(0,0,-1), + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,1,0), + vector.new(0,-1,0), + }, nodes_to_content_ids = {}, content_ids_to_nodes = {}, vm_data = {}, @@ -182,7 +233,11 @@ function ns.register_tool(name, def) end function ns.register_entity(name, def) - minetest.register_entity(name, def) + def._name = name + if not name:find(":") then + name = "red_glazed_terracotta:"..name + end + minetest.register_entity(":"..name, def) end -- Make node dig particles denser. @@ -207,6 +262,46 @@ minetest.register_on_dignode(function(pos, node, digger) }) end) +-- HACK: Lookup table for getting a rotation from a +-- facedir (because Minetest doesn't have any way +-- to get this information normally) +local facedir_rotations = { + -- +Y + [0] = vector.new(0, 0, 0), + [1] = vector.new(0, math.pi * 1.5, 0), + [2] = vector.new(0, math.pi * 1.0, 0), + [3] = vector.new(0, math.pi * 0.5, 0), + -- +Z + [4] = vector.new(math.pi * 1.5, 0, 0), + [5] = vector.new(0, math.pi * 1.5, math.pi * 1.5), + [6] = vector.new(math.pi * 0.5, math.pi * 1.0, 0), + [7] = vector.new(0, math.pi * 0.5, math.pi * 0.5), + -- -Z + [8] = vector.new(math.pi * 0.5, 0, 0), + [9] = vector.new(0, math.pi * 1.5, math.pi * 0.5), + [10] = vector.new(math.pi * 1.5, math.pi * 1.0, 0), + [11] = vector.new(0, math.pi * 0.5, math.pi * 1.5), + -- +X + [12] = vector.new(0, 0, math.pi * 0.5), + [13] = vector.new(math.pi * 1.5, math.pi * 1.5, 0), + [14] = vector.new(0, math.pi * 1.0, math.pi * 1.5), + [15] = vector.new(math.pi * 0.5, math.pi * 0.5, 0), + -- -X + [16] = vector.new(0, 0, math.pi * 1.5), + [17] = vector.new(math.pi * 0.5, math.pi * 1.5, 0), + [18] = vector.new(0, math.pi * 1.0, math.pi * 0.5), + [19] = vector.new(math.pi * 1.5, math.pi * 0.5, 0), + -- -Y + [20] = vector.new(0, 0, math.pi * 1.0), + [21] = vector.new(0, math.pi * 0.5, math.pi * 1.0), + [22] = vector.new(0, math.pi * 1.0, math.pi * 1.0), + [23] = vector.new(0, math.pi * 1.5, math.pi * 1.0), +} + +function ns.facedir_to_rotation(facedir) + return facedir_rotations[facedir] or minetest.facedir_to_dir(facedir):dir_to_rotation() +end + -- Fills the area from pos1 to pos2 with the node named `node`. function ns.fill_area(pos1, pos2, node) local minp = vector.new(math.min(pos1.x, pos2.x), math.min(pos1.y, pos2.y), math.min(pos1.z, pos2.z)) @@ -255,6 +350,18 @@ function ns.get_node_meta(pos) return setmetatable({_pos = tostring(minetest.hash_node_position(pos))}, NodeMetaRef) end +ns.clock = EventTarget() + +local seconds = minetest.get_us_time() +minetest.register_globalstep(function(dtime) + ns.clock:dispatch("tick", dtime) + local time = minetest.get_us_time() + if time - seconds >= 1000000 then + ns.clock:dispatch("every_second", dtime) + seconds = time + end +end) + -- Allow nodes to provide a callback to run on activation without -- needing to register a bunch of mostly identical LBMs. minetest.register_lbm { diff --git a/mods/rgt_cosmetics/init.lua b/mods/rgt_cosmetics/init.lua index 3a5312a..2cedaf6 100644 --- a/mods/rgt_cosmetics/init.lua +++ b/mods/rgt_cosmetics/init.lua @@ -58,7 +58,7 @@ function rgt.register_hand(name, caps, realname) drawtype = "mesh", mesh = "rgt_hand.gltf", tiles = {"rgt_base_"..(realname or name or "placeholder")..".png"}, - use_texture_alpha = "opaque", + use_texture_alpha = "clip", visual_scale = 1, wield_scale = vector.new(2,2,2), node_placement_prediction = "", diff --git a/mods/rgt_hud/init.lua b/mods/rgt_hud/init.lua index d22e876..dc9f127 100644 --- a/mods/rgt_hud/init.lua +++ b/mods/rgt_hud/init.lua @@ -305,6 +305,32 @@ ns.register_hud_type { end } +ns.register_hud_type { + name = "waypoint", + required_fields = {"world_pos"}, + field_types = { + scale = "vec2" + }, + defaults = { + scale = {x=1,y=1} + }, + add = function(e, m) + e._id = m.object:hud_add { + type = "waypoint", + world_pos = e.world_pos, + text = e.text + } + end, + update = function(e, m, changes) + for k, v in pairs(changes) do + m.object:hud_change(e._id, k, v) + end + end, + remove = function(e, m) + m.object:hud_remove(e._id) + end +} + minetest.register_chatcommand("hudtest", { func = function(name) ns.hud_add(rgt.players[name], { diff --git a/mods/rgt_inv/init.lua b/mods/rgt_inv/init.lua index 7ed2b8f..5f0f469 100644 --- a/mods/rgt_inv/init.lua +++ b/mods/rgt_inv/init.lua @@ -9,13 +9,20 @@ local creative_inv = minetest.create_detached_inventory("rgt_creative_inv", { local num_items = 0 minetest.register_on_mods_loaded(function() + local items = {} for name, def in pairs(minetest.registered_items) do if not def._variant then - creative_inv:set_size("main", num_items +1) - creative_inv:set_stack("main", num_items, ItemStack(name.." "..def.stack_max)) + items[num_items +1] = name.." "..def.stack_max num_items = num_items +1 end end + + table.sort(items) + + for i, x in ipairs(items) do + creative_inv:set_size("main", num_items) + creative_inv:set_stack("main", i, ItemStack(x)) + end end) Inventory = setmetatable({ diff --git a/mods/rgt_machines/rgt_machines/init.lua b/mods/rgt_machines/rgt_machines/init.lua index 0690fd6..51dbc5d 100644 --- a/mods/rgt_machines/rgt_machines/init.lua +++ b/mods/rgt_machines/rgt_machines/init.lua @@ -4,4 +4,104 @@ rgt_machines = { } local ns = rgt_machines +-- Recursively propagate a network reassignment to all connected nodes (ignoring positions in `ignore`). +local function propagate_network_update(pos, net, net_type, ignore) + ignore[minetest.hash_node_position(pos)] = true + -- Store the network to the target node. + local m = minetest.get_meta(pos) + m:set_string("network", net) + m:set_string("network_type", net_type) + -- Check each neighboring node for further propagation. + for _, x in ipairs(rgt.adjacent_neighbor_offests) do + -- If we already checked this node, we shouldn't consider it to avoid infinite recursion. + if not ignore[minetest.hash_node_position(pos +x)] then + local ncid, _, nparam2 = minetest.get_node_raw(pos.x +x.x, pos.y +x.y, pos.z +x.z) + local ndef = minetest.registered_nodes[rgt.content_ids_to_nodes[ncid]] + -- Ensure that this node can belong to a network and thus is a valid propagation target. + if ndef._network_can_accept and ndef._network_can_accept(pos, nparam2) then + propagate_network_update(pos +x, net, ignore) + end + end + end +end +-- Called when a pos is added to or removed from a network. +-- Whether an addition or deletion is being performed depends on whether the node at `pos` belongs to the `network_component` group. +function ns.update_network(pos, net_type) + local cid, _, param2 = minetest.get_node_raw(pos.x, pos.y, pos.z) + local def = minetest.registered_nodes[rgt.content_ids_to_nodes[cid]] + -- We're adding a node. + if def._network_neighbors then + -- Find all adjacent networks. + local net + local nets = {} + local num_nets = 0 + for _, x in ipairs(def._network_neighbors(pos, param2)) do + local ncid, _, nparam2 = minetest.get_node_raw(pos.x +x.x, pos.y +x.y, pos.z +x.z) + local ndef = minetest.registered_nodes[rgt.content_ids_to_nodes[ncid]] + -- Ensure that this node can accept a network propagation from this position. + if ndef._network_can_accept and ndef._network_can_accept(pos, nparam2) then + local m = minetest.get_meta(pos +x) + local n = m:get("network") + local nt = m:get("network_type") + -- If the node doesn't have a network for some reason, we should give it one. + if nt == net_type and not n or table.indexof(nets, n) == -1 then + -- Set our network to the first one we find. + if not net then + net = n + -- Store the positions of any other adjacent networks, so we can merge them with ours. + elseif net ~= n then + nets[#nets +1] = x + end + num_nets = num_nets +1 + end + end + end + + -- Propagate our chosen network to adjacent networks with different IDs. + -- If we didn't find any adjacent networks, this will just do nothing. + local ignore = {[minetest.hash_node_position(pos)] = true} + for _, x in ipairs(nets) do + propagate_network_update(pos +x, net, net_type, ignore) + end + + -- Create a new unique network ID if none of our neighbors have one. + if not net then + net = string.format("net_%d_%06d", minetest.get_us_time(), math.random(100000, 999999)) + end + + -- Save our chosen network ID. + local m = minetest.get_meta(pos) + m:set_string("network", net) + m:set_string("network_type", net_type) + -- We're removing a node. + else + -- Find all adjacent networks. + local net + local nets = {} + for _, x in ipairs(rgt.adjacent_neighbor_offests) do + local ncid, _, nparam2 = minetest.get_node_raw(pos.x +x.x, pos.y +x.y, pos.z +x.z) + local ndef = minetest.registered_nodes[rgt.content_ids_to_nodes[ncid]] + -- Ensure that this node can accept a network propagation from this position. + if ndef._network_can_accept and ndef._network_can_accept(pos, nparam2) then + local m = minetest.get_meta(pos +x) + local n = m:get("network") + local nt = m:get("network_type") + if nt == net_type then + nets[#nets +1] = x + end + end + end + -- We only need to ensure that these networks are unique, thus one of them can keep its original ID. + if #nets > 1 then table.remove(nets, 1) end + + -- Create a new ID for each network and propagate it. + local pos_hash = minetest.hash_node_position(pos) + for _, 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_network_update(pos +x, net, net_type, {[pos_hash] = true}) + end + end + return true +end diff --git a/mods/rgt_machines/rgt_machines_electric/rgt_machines_electric/init.lua b/mods/rgt_machines/rgt_machines_electric/rgt_machines_electric/init.lua index 6334cf9..a06896a 100644 --- a/mods/rgt_machines/rgt_machines_electric/rgt_machines_electric/init.lua +++ b/mods/rgt_machines/rgt_machines_electric/rgt_machines_electric/init.lua @@ -70,7 +70,7 @@ end -- Called when a pos is added to or removed from a network. -- Whether an addition or deletion is being performed depends on whether the node at `pos` belongs to the `network_component` group. -function ns.update_network(pos) +function ns.update_network_(pos) -- We're adding a node. if minetest.get_item_group(minetest.get_node(pos).name, "network_component") > 0 then -- Find all adjacent networks. diff --git a/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/init.lua b/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/init.lua index 06d394a..31e7382 100644 --- a/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/init.lua +++ b/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/init.lua @@ -1,22 +1,631 @@ local ns = rgt_machines -ns.components = {} +local db = minetest.get_mod_storage() ---[[ - { - name = "...", -- The component's name. - attach_points +local shaft_networks = {} + +local shafts = {} + +local ShaftNetwork +ShaftNetwork = { + init = function(id) + local e = { + id = id, + torque = ModifierStack(), + load = ModifierStack(), + inertia = ModifierStack(), + alpha = 0, + omega = 0, + angle = 0, + } + setmetatable(e, {__index = ShaftNetwork}) + local saved = minetest.deserialize(db:get(id)) + if saved then + e:read(saved) + end + function e._update() e:update() end + e.torque:listen("change", e._update) + e.inertia:listen("change", e._update) + function e._tick(...) e:tick(...) end + rgt.clock:listen("tick", e._tick) + return e + end, + deinit = function(e) + e:save() + rgt.clock:unlisten("tick", e._tick) + end, + read = function(e, saved) + for k, v in pairs(saved.torque) do + e.torque:set(k, v) + end + for k, v in pairs(saved.load) do + e.load:set(k, v) + end + for k, v in pairs(saved.inertia) do + e.inertia:set(k, v) + end + e.alpha = saved.alpha + e.omega = saved.omega + end, + store = function(e) + local out = { + torque = {}, + load = {}, + inertia = {}, + alpha = e.alpha, + omega = e.omega, + angle = e.angle, + } + for k, v in pairs(e.torque) do + if k ~= "value" and k ~= "mode" and k ~= "listeners" then out.torque[k] = v end + end + for k, v in pairs(e.load) do + if k ~= "value" and k ~= "mode" and k ~= "listeners" then out.load[k] = v end + end + for k, v in pairs(e.inertia) do + if k ~= "value" and k ~= "mode" and k ~= "listeners" then out.inertia[k] = v end + end + return out + end, + save = function(e) + db:set_string(e.id, minetest.serialize(e:store())) + 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 + e.omega = e.omega +(e.alpha *dtime) + + if math.abs(e.omega) < 0.05 then + e.alpha = 0 + e.omega = 0 + end + + e.angle = (e.angle +(e.omega *dtime)) %(math.pi *200) + + for i = 1, #e do + e[i]:set_angle(e.angle) + end + end, + update = function(e, dtime) + end, +} +setmetatable(ShaftNetwork, { + __call = function(_, ...) + return ShaftNetwork.init(...) + end +}) + +local function propagate_shaft_update(pos, net, ignore) + local cid, _, param2 = minetest.get_node_raw(pos.x, pos.y, pos.z) + local def = minetest.registered_nodes[rgt.content_ids_to_nodes[cid]] + local hashed_pos = minetest.hash_node_position(pos) + ignore[hashed_pos] = true + -- Store the network to the target node. + local m = minetest.get_meta(pos) + local old_net = m:get("network") + if shaft_networks[old_net] then + for i = 1, #shaft_networks[old_net] do + 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()) + end + e:change_network(net) + end + end + end + m:set_string("network", net) + -- Check each neighboring node for further propagation. + for _, x in ipairs(def._network_neighbors(pos, param2)) do + -- If we already checked this node, we shouldn't consider it to avoid infinite recursion. + if not ignore[minetest.hash_node_position(x)] then + local ncid, _, nparam2 = minetest.get_node_raw(x.x, x.y, x.z) + local ndef = minetest.registered_nodes[rgt.content_ids_to_nodes[ncid]] + -- Ensure that this node can belong to a network and thus is a valid propagation target. + if ndef and minetest.get_item_group(ndef.name, "shaft") > 0 and ndef._network_can_accept and ndef._network_can_accept(x, pos, nparam2) then + propagate_shaft_update(x, net, ignore) + end + end + end +end + +function ns.update_shaft(pos, removing, ignore) + local cid, _, param2 = minetest.get_node_raw(pos.x, pos.y, pos.z) + local def = minetest.registered_nodes[rgt.content_ids_to_nodes[cid]] + + if not removing then + -- Find all adjacent networks. + local net + local nets = {} + local num_nets = 0 + for _, x in ipairs(def._network_neighbors(pos, param2)) do + local ncid, _, nparam2 = minetest.get_node_raw(x.x, x.y, x.z) + local ndef = minetest.registered_nodes[rgt.content_ids_to_nodes[ncid]] + -- Ensure that this node can accept a network propagation from this position. + if ndef and minetest.get_item_group(ndef.name, "shaft") > 0 and ndef._network_can_accept and ndef._network_can_accept(x, pos, nparam2) then + local m = minetest.get_meta(x) + local n = m:get("network") + -- If the node doesn't have a network for some reason, we should give it one. + if not n or table.indexof(nets, n) == -1 then + -- Set our network to the first one we find. + if not net then + net = n + -- Store the positions of any other adjacent networks, so we can merge them with ours. + elseif net ~= n then + nets[#nets +1] = x + end + num_nets = num_nets +1 + end + end + end + + -- Create a new unique network ID if none of our neighbors have one. + if not net then + net = string.format("net_%d_%06d", minetest.get_us_time(), math.random(100000, 999999)) + end + + -- Propagate our chosen network to adjacent networks with different IDs. + -- If we didn't find any adjacent networks, this will just do nothing. + local ignore = {[minetest.hash_node_position(pos)] = true} + for _, x in ipairs(nets) do + propagate_shaft_update(x, net, ignore) + end + + -- Save our chosen network ID. + local m = minetest.get_meta(pos) + m:set_string("network", net) + return net + else + -- Find all adjacent networks. + local net + local nets = {} + for _, x in ipairs(def._network_neighbors(pos, param2)) do + local ncid, _, nparam2 = minetest.get_node_raw(x.x, x.y, x.z) + local ndef = minetest.registered_nodes[rgt.content_ids_to_nodes[ncid]] + -- Ensure that this node can accept a network propagation from this position. + if ndef and minetest.get_item_group(ndef.name, "shaft") > 0 and ndef._network_can_accept and ndef._network_can_accept(x, pos, nparam2) then + local m = minetest.get_meta(x) + local n = m:get("network") + nets[#nets +1] = x + end + end + -- We only need to ensure that these networks are unique, thus one of them can keep its original ID. +-- if #nets > 0 then table.remove(nets, 1) end + + -- Create a new ID for each network and propagate it. + local pos_hash = minetest.hash_node_position(pos) + 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"}) + end + end +end + +rgt.register_entity("shaft", { + initial_properties = { + visual = "mesh", + mesh = "rgt_shaft.gltf", + textures = {"rgt_shaft.png"}, + pointable = false, + }, + on_activate = function(e, data) + e.pos = e.object:get_pos():round() + + if shafts[minetest.hash_node_position(e.pos)] or not minetest.get_node(e.pos).name:find "shaft" then + e.object:remove() + return + end + extend(e, minetest.deserialize(data or "return {}")) + + e.omega = 0 + e.angle = e.angle or 0 + + e.object:set_armor_groups{immortal = 1} + + e.object:set_rotation(e.rotation) + + shafts[minetest.hash_node_position(e.pos)] = e + if not shaft_networks[e.net] then + 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) + table.insert(shaft_networks[e.net], e) + end, + on_deactivate = function(e) + shafts[minetest.hash_node_position(e.pos)] = nil + if not shaft_networks[e.net][1] then + table.remove(shaft_networks[e.net], table.indexof(shaft_networks[e.net], e)) + shaft_networks[e.net]:deinit() + shaft_networks[e.net] = nil + end + end, + get_staticdata = function(e) + return minetest.serialize{rotation = e.rotation, invert = e.invert, net = e.net} + 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)) + 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(), 1) + end, + set_angle = function(e, angle) +-- e.object:set_properties { +-- nametag = e.net +-- } + e.object:set_bone_override("root", { + rotation = { + vec = vector.new(0, 0, e.invert and angle or -angle), + interpolation = 0.1, + absolute = true + } + }) + end +}) + +local shaft_box = { + type = "fixed", + fixed = { + -3/16, -3/16, -0.5, + 3/16, 3/16, 0.5 } ---]] -function ns.register_component(def) - ns.components[def.name] = def -end +} -function ns.register_plate(name, def) - rgt.register_item(name, def) -end +rgt.register_node("shaft", { + drawtype = "airlike", + paramtype = "light", + paramtype2 = "facedir", + selection_box = shaft_box, + collision_box = shaft_box, + groups = {shaft = 1, dig_immediate = 3}, + entities = shafts, + + on_place = function(s, p, pt) + 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) + end + + 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 + if neighbor:distance(target) <= 1 then + return minetest.item_place_node(s, p, pt, minetest.get_node(neighbor).param2) + end + end + end + + return minetest.item_place_node(s, p, pt) + end, + on_construct = function(pos) + local param2 = minetest.get_node(pos).param2 + local dir = minetest.facedir_to_dir(param2) + + local net = ns.update_shaft(pos) + minetest.add_entity(pos, "red_glazed_terracotta:shaft", minetest.serialize{rotation = rgt.facedir_to_rotation(param2), invert = dir.x < 0 or dir.z < 0, net = net}) + end, + on_destruct = function(pos) + local e = shafts[minetest.hash_node_position(pos)] + shaft_networks[e.net].inertia:set(pos:to_string(), nil) + e.object:remove() + shafts[minetest.hash_node_position(pos)] = nil + ns.update_shaft(pos, true) + end, + + _network_can_accept = function(pos, from, param2) + local dir = minetest.facedir_to_dir(param2) + + return dir:abs() == from:direction(pos):abs() + end, + _network_neighbors = function(pos, param2) + local param2 = minetest.get_node(pos).param2 + local dir = minetest.facedir_to_dir(param2) + + return {pos +dir, pos -dir} + end, +}) +local hand_cranks = {} + +rgt.register_entity("hand_crank", { + initial_properties = { + visual = "mesh", + mesh = "rgt_hand_crank.gltf", + textures = {"rgt_hand_crank.png"}, + pointable = false + }, + on_activate = function(e, data) + e.pos = e.object:get_pos():round() + + if hand_cranks[minetest.hash_node_position(e.pos)] or not minetest.get_node(e.object:get_pos()).name:find "hand_crank" then + e.object:remove() + return + end + extend(e, minetest.deserialize(data or "return {}")) + + e.rotation = vector.new(e.rotation.x, e.rotation.y, e.rotation.z) + + e.torque = 0 + e.omega = 0 + e.angle = e.angle or 0 + + e.object:set_armor_groups{immortal = 1} + + e.object:set_rotation(e.rotation) + + hand_cranks[minetest.hash_node_position(e.pos)] = e + if not shaft_networks[e.net] then + 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) + table.insert(shaft_networks[e.net], e) + end, + on_deactivate = function(e) + hand_cranks[minetest.hash_node_position(e.pos)] = nil + table.remove(shaft_networks[e.net], table.indexof(shaft_networks[e.net], e)) + 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, invert = e.invert, net = e.net} + end, + on_step = function(e, dtime) + if not e.cranking then + e:set_torque(math.max(0, e.torque -1)) + end + end, + + change_network = function(e, new_net) + local net = shaft_networks[e.net] + net.inertia:set(e.pos:to_string(), nil) + net.torque: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(), 1) + 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)) + 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) +-- } + e.object:set_bone_override("root", { + rotation = { + vec = vector.new(0, 0, e.invert and angle or -angle), + interpolation = 0.1, + absolute = true + } + }) + end, +}) + +local function do_crank(m) + local crank = hand_cranks[m.cranking] + if not crank then return m:unlisten("tick", do_crank) end + if not m.ctl.place or not m.pointed_node or m.pointed_node.under ~= crank.pos then + m:unlisten("tick", do_crank) + crank.cranking = nil + m.cranking = nil + return + end + + crank:add_torque() +end rgt.register_node("hand_crank", { - mesh = "rgt_hand_crank.gltf" + drawtype = "airlike", + paramtype = "light", + paramtype2 = "facedir", + walkable = false, + selection_box = { + type = "fixed", + fixed = { + -0.5, -0.5, 0.5, + 0.5, 0.5, 6/16 + } + }, + groups = {shaft = 2, dig_immediate = 3}, + entities = hand_cranks, + + on_construct = function(pos) + local param2 = minetest.get_node(pos).param2 + local dir = minetest.facedir_to_dir(param2) + local angle + + 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:hand_crank", minetest.serialize{rotation = rgt.facedir_to_rotation(minetest.get_node(pos).param2), angle = angle, invert = dir.x < 0 or dir.z < 0, net = ns.update_shaft(pos)}) + end, + on_destruct = function(pos) + local e = hand_cranks[minetest.hash_node_position(pos)] + shaft_networks[e.net].inertia:set(e.pos:to_string(), nil) + e.object:remove() + hand_cranks[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) + hand_cranks[m.cranking].cranking = true + m:listen("tick", do_crank) + end, + + _network_can_accept = function(pos, from, param2) + local dir = minetest.facedir_to_dir(param2) + + return dir == pos:direction(from) + end, + _network_neighbors = function(pos, param2) + local param2 = minetest.get_node(pos).param2 + local dir = minetest.facedir_to_dir(param2) + local angle + + 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 {} + end +}) + +local load_testers = {} + +rgt.register_entity("shaft_load_tester", { + initial_properties = { + visual = "mesh", + mesh = "rgt_shaft.gltf", + textures = {"rgt_shaft.png"}, + 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 + 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.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 + 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) + 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 + table.remove(shaft_networks[e.net], table.indexof(shaft_networks[e.net], e)) + shaft_networks[e.net]:save() + shaft_networks[e.net] = nil + end + end, + get_staticdata = function(e) + return minetest.serialize{rotation = e.rotation, angle = e.angle, 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", { + rotation = { + vec = vector.new(0, 0, -e.angle), + 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 = { + type = "fixed", + fixed = { + -0.5, -0.5, 0.5, + 0.5, 0.5, 6/16 + } + }, + groups = {shaft = 2, dig_immediate = 3}, + entities = load_testers, + + on_construct = function(pos) + local param2 = minetest.get_node(pos).param2 + local dir = minetest.facedir_to_dir(param2) + local angle + + 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)}) + end, + on_destruct = function(pos) + load_testers[minetest.hash_node_position(pos)].object:remove() + load_testers[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) + + return dir == pos:direction(from) + end, + _network_neighbors = function(pos, param2) + local param2 = minetest.get_node(pos).param2 + local dir = minetest.facedir_to_dir(param2) + local angle + + 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 {} + end }) diff --git a/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_hand_crank.gltf b/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_hand_crank.gltf new file mode 100644 index 0000000..b778e08 --- /dev/null +++ b/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_hand_crank.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0","generator":"Blockbench 4.12.5 glTF exporter"},"scenes":[{"nodes":[7],"name":"blockbench_export"}],"scene":0,"nodes":[{"rotation":[6.123233995736775e-17,1,6.123233995736775e-17,-1.4849232954361467e-15],"translation":[0,0,3.125],"name":"cube","mesh":0},{"rotation":[6.123233995736775e-17,1,6.123233995736775e-17,-1.4849232954361467e-15],"translation":[0,0,3.125],"name":"cube","mesh":1},{"translation":[0,-0.625,3.125],"name":"cube","mesh":2},{"rotation":[-0.38268343236508984,-0.9238795325112867,8.798212023370643e-16,9.370841095930147e-16],"translation":[0,6.938893903907228e-17,6.938893903907228e-17],"name":"cube","mesh":3},{"rotation":[-0.38268343236508984,-0.9238795325112867,8.798212023370643e-16,9.370841095930147e-16],"translation":[0,6.938893903907228e-17,6.938893903907228e-17],"name":"cube","mesh":4},{"translation":[5,-4.85722573273506e-16,3.7499999999999907],"name":"handle","children":[3,4]},{"translation":[0,0,-3.125],"name":"root","children":[0,1,2,5]},{"children":[6]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":840,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1128,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1416,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":1608,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":1680,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1968,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2256,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":2448,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":2520,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2808,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":3096,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":3288,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":3360,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":3648,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":3936,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":4128,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":4200,"byteLength":16},{"buffer":0,"byteOffset":4216,"byteLength":64},{"buffer":0,"byteOffset":4280,"byteLength":16},{"buffer":0,"byteOffset":4296,"byteLength":64}],"buffers":[{"byteLength":4360,"uri":"data:application/octet-stream;base64,AADwPwAA8D8AAKBAAADwPwAA8D8AAKA/AADwPwAA8L8AAKBAAADwPwAA8L8AAKA/AADwvwAA8D8AAKA/AADwvwAA8D8AAKBAAADwvwAA8L8AAKA/AADwvwAA8L8AAKBAAADwvwAA8D8AAKA/AADwPwAA8D8AAKA/AADwvwAA8D8AAKBAAADwPwAA8D8AAKBAAADwvwAA8L8AAKBAAADwPwAA8L8AAKBAAADwvwAA8L8AAKA/AADwPwAA8L8AAKA/AADwvwAA8D8AAKBAAADwPwAA8D8AAKBAAADwvwAA8L8AAKBAAADwPwAA8L8AAKBAAADwPwAA8D8AAKA/AADwvwAA8D8AAKA/AADwPwAA8L8AAKA/AADwvwAA8L8AAKA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AABAPgAA4D4AAMA+AADgPgAAQD4AACA/AADAPgAAID8AAPA+AAAAAAAAKD8AAAAAAADwPgAAQD4AACg/AABAPgAAKD8AAMA+AADwPgAAwD4AACg/AABAPgAA8D4AAEA+AABAPwAAwD4AABA/AADAPgAAQD8AABA/AAAQPwAAED8AAMA+AADgPgAAED8AAOA+AADAPgAAID8AABA/AAAgPwAAAAAAAOA+AABAPgAA4D4AAAAAAAAgPwAAQD4AACA/AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAABIQAAAoD8AACBAAABIQAAAoD8AACA/AABIQAAAoL8AACBAAABIQAAAoL8AACA/AADIwAAAoD8AACA/AADIwAAAoD8AACBAAADIwAAAoL8AACA/AADIwAAAoL8AACBAAADIwAAAoD8AACA/AABIQAAAoD8AACA/AADIwAAAoD8AACBAAABIQAAAoD8AACBAAADIwAAAoL8AACBAAABIQAAAoL8AACBAAADIwAAAoL8AACA/AABIQAAAoL8AACA/AADIwAAAoD8AACBAAABIQAAAoD8AACBAAADIwAAAoL8AACBAAABIQAAAoL8AACBAAABIQAAAoD8AACA/AADIwAAAoD8AACA/AABIQAAAoL8AACA/AADIwAAAoL8AACA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACwPgAAID8AAOA+AAAgPwAAsD4AAEA/AADgPgAAQD8AAOA+AAAgPwAACD8AACA/AADgPgAAQD8AAAg/AABAPwAA8D4AALA+AAAAAAAAsD4AAPA+AACAPgAAAAAAAIA+AADwPgAAsD4AAAAAAACwPgAA8D4AAOA+AAAAAAAA4D4AAAAAAAAAPgAA8D4AAAA+AAAAAAAAgD4AAPA+AACAPgAAAAAAAAAAAADwPgAAAAAAAAAAAAAAPgAA8D4AAAA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAgPwAAoD8AAAAAAAAgPwAAoD8AACC/AAAgPwAAAAAAAAAAAAAgPwAAAAAAACC/AAAgvwAAoD8AACC/AAAgvwAAoD8AAAAAAAAgvwAAAAAAACC/AAAgvwAAAAAAAAAAAAAgvwAAoD8AACC/AAAgPwAAoD8AACC/AAAgvwAAoD8AAAAAAAAgPwAAoD8AAAAAAAAgvwAAAAAAAAAAAAAgPwAAAAAAAAAAAAAgvwAAAAAAACC/AAAgPwAAAAAAACC/AAAgvwAAoD8AAAAAAAAgPwAAoD8AAAAAAAAgvwAAAAAAAAAAAAAgPwAAAAAAAAAAAAAgPwAAoD8AACC/AAAgvwAAoD8AACC/AAAgPwAAAAAAACC/AAAgvwAAAAAAACC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAIPwAAwD4AABA/AADAPgAACD8AAOA+AAAQPwAA4D4AAAg/AAAgPwAAED8AACA/AAAIPwAAMD8AABA/AAAwPwAAID8AADA/AAAQPwAAMD8AACA/AAAoPwAAED8AACg/AAAwPwAAKD8AACA/AAAoPwAAMD8AADA/AAAgPwAAMD8AACg/AABAPgAAOD8AAEA+AAAoPwAAgD4AADg/AACAPgAA8D4AAMA+AAAIPwAAwD4AAPA+AADgPgAACD8AAOA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAgPwAAID8AAKA/AAAgPwAAID8AACA/AAAgPwAAIL8AAKA/AAAgPwAAIL8AACA/AAAgvwAAID8AACA/AAAgvwAAID8AAKA/AAAgvwAAIL8AACA/AAAgvwAAIL8AAKA/AAAgvwAAID8AACA/AAAgPwAAID8AACA/AAAgvwAAID8AAKA/AAAgPwAAID8AAKA/AAAgvwAAIL8AAKA/AAAgPwAAIL8AAKA/AAAgvwAAIL8AACA/AAAgPwAAIL8AACA/AAAgvwAAID8AAKA/AAAgPwAAID8AAKA/AAAgvwAAIL8AAKA/AAAgPwAAIL8AAKA/AAAgPwAAID8AACA/AAAgvwAAID8AACA/AAAgPwAAIL8AACA/AAAgvwAAIL8AACA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAIPwAAMD8AABA/AAAwPwAACD8AAEA/AAAQPwAAQD8AABA/AAAwPwAAGD8AADA/AAAQPwAAQD8AABg/AABAPwAAKD8AADg/AAAYPwAAOD8AACg/AAAwPwAAGD8AADA/AAA4PwAAMD8AACg/AAAwPwAAOD8AADg/AAAoPwAAOD8AACg/AACgPgAAOD8AAKA+AAAoPwAAwD4AADg/AADAPgAAKD8AAIA+AAA4PwAAgD4AACg/AACgPgAAOD8AAKA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAABwPwAAcD8AACA/AABwPwAAcD8AACDAAABwPwAAcL8AACA/AABwPwAAcL8AACDAAABwvwAAcD8AACDAAABwvwAAcD8AACA/AABwvwAAcL8AACDAAABwvwAAcL8AACA/AABwvwAAcD8AACDAAABwPwAAcD8AACDAAABwvwAAcD8AACA/AABwPwAAcD8AACA/AABwvwAAcL8AACA/AABwPwAAcL8AACA/AABwvwAAcL8AACDAAABwPwAAcL8AACDAAABwvwAAcD8AACA/AABwPwAAcD8AACA/AABwvwAAcL8AACA/AABwPwAAcL8AACA/AABwPwAAcD8AACDAAABwvwAAcD8AACDAAABwPwAAcL8AACDAAABwvwAAcL8AACDAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAQPwAAED8AADg/AAAQPwAAED8AACg/AAA4PwAAKD8AAAAAAAAgPwAAID4AACA/AAAAAAAAOD8AACA+AAA4PwAAgD4AAEg/AAAgPgAASD8AAIA+AAAgPwAAID4AACA/AACwPgAAID8AAIA+AAAgPwAAsD4AAEg/AACAPgAASD8AACg/AADAPQAAQD8AAMA9AAAoPwAAQD4AAEA/AABAPgAAKD8AAAAAAABAPwAAAAAAACg/AADAPQAAQD8AAMA9AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAAAKuqqj6rqio/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAANezXb8AAAA/AAAAAAAAAIDXs12/AAAAvwAAAAAAAACAMjENpQAAgL8AAAAAq6qqPquqKj8AAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAA17NdPwAAAD8AAACAAAAAANezXT8AAAC/AAAAgAAAAAAyMQ0lAACAvw=="}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1.875,1.875,5],"min":[-1.875,-1.875,1.25],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[0.75,0.625],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":4,"componentType":5126,"count":24,"max":[3.125,1.25,2.5],"min":[-6.25,-1.25,0.625],"type":"VEC3"},{"bufferView":5,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":6,"componentType":5126,"count":24,"max":[0.53125,0.75],"min":[0,0],"type":"VEC2"},{"bufferView":7,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":8,"componentType":5126,"count":24,"max":[0.625,1.25,0],"min":[-0.625,0,-0.625],"type":"VEC3"},{"bufferView":9,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":10,"componentType":5126,"count":24,"max":[0.71875,0.6875],"min":[0.46875,0.1875],"type":"VEC2"},{"bufferView":11,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":12,"componentType":5126,"count":24,"max":[0.625,0.625,1.25],"min":[-0.625,-0.625,0.625],"type":"VEC3"},{"bufferView":13,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":14,"componentType":5126,"count":24,"max":[0.71875,0.75],"min":[0.53125,0.25],"type":"VEC2"},{"bufferView":15,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":16,"componentType":5126,"count":24,"max":[0.9375,0.9375,0.625],"min":[-0.9375,-0.9375,-2.5],"type":"VEC3"},{"bufferView":17,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":18,"componentType":5126,"count":24,"max":[0.75,0.78125],"min":[0,0],"type":"VEC2"},{"bufferView":19,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":20,"componentType":5126,"count":4,"max":[1],"min":[0],"type":"SCALAR"},{"bufferView":21,"componentType":5126,"count":4,"max":[0,0,0,1],"min":[0,0,-0.8660253882408142,-1],"type":"VEC4"},{"bufferView":22,"componentType":5126,"count":4,"max":[1],"min":[0],"type":"SCALAR"},{"bufferView":23,"componentType":5126,"count":4,"max":[0,0,0.8660253882408142,1],"min":[0,0,0,-1],"type":"VEC4"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{"sampler":0,"source":0,"name":"rgt_hand_crank"}],"samplers":[{"magFilter":9728,"minFilter":9728,"wrapS":33071,"wrapT":33071}],"images":[{"mimeType":"image/png","name":"rgt_hand_crank.png","uri":"rgt_hand_crank.png"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":4,"NORMAL":5,"TEXCOORD_0":6},"indices":7,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":8,"NORMAL":9,"TEXCOORD_0":10},"indices":11,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":12,"NORMAL":13,"TEXCOORD_0":14},"indices":15,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":16,"NORMAL":17,"TEXCOORD_0":18},"indices":19,"material":0}]}],"animations":[{"name":"animation","samplers":[{"input":20,"output":21,"interpolation":"LINEAR"},{"input":22,"output":23,"interpolation":"LINEAR"}],"channels":[{"sampler":0,"target":{"node":6,"path":"rotation"}},{"sampler":1,"target":{"node":5,"path":"rotation"}}]}]} \ No newline at end of file diff --git a/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_shaft.gltf b/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_shaft.gltf new file mode 100644 index 0000000..59ce446 --- /dev/null +++ b/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/models/rgt_shaft.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0","generator":"Blockbench 4.12.5 glTF exporter"},"scenes":[{"nodes":[2],"name":"blockbench_export"}],"scene":0,"nodes":[{"name":"cube","mesh":0},{"name":"root","children":[0]},{"children":[1]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":840,"byteLength":16},{"buffer":0,"byteOffset":856,"byteLength":64}],"buffers":[{"byteLength":920,"uri":"data:application/octet-stream;base64,AADwPwAA8D8AAKBAAADwPwAA8D8AAKDAAADwPwAA8L8AAKBAAADwPwAA8L8AAKDAAADwvwAA8D8AAKDAAADwvwAA8D8AAKBAAADwvwAA8L8AAKDAAADwvwAA8L8AAKBAAADwvwAA8D8AAKDAAADwPwAA8D8AAKDAAADwvwAA8D8AAKBAAADwPwAA8D8AAKBAAADwvwAA8L8AAKBAAADwPwAA8L8AAKBAAADwvwAA8L8AAKDAAADwPwAA8L8AAKDAAADwvwAA8D8AAKBAAADwPwAA8D8AAKBAAADwvwAA8L8AAKBAAADwPwAA8L8AAKBAAADwPwAA8D8AAKDAAADwvwAA8D8AAKDAAADwPwAA8L8AAKDAAADwvwAA8L8AAKDAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAAA/AAAAAAAAAAAAAEA+AAAAPwAAQD4AAAAAAABAPgAAAD8AAEA+AAAAAAAAwD4AAAA/AADAPgAAQD4AAGA/AAAAAAAAYD8AAEA+AADAPgAAAAAAAMA+AADAPgAAwD4AAEA+AADAPgAAwD4AAGA/AABAPgAAYD8AAAA/AAAAAAAAMD8AAAAAAAAAPwAAQD4AADA/AABAPgAAwD4AAMA+AAAQPwAAwD4AAMA+AAAQPwAAED8AABA/AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAAAKuqqj6rqio/AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAANezXb8AAAA/AAAAAAAAAIDXs12/AAAAvwAAAAAAAACAMjENpQAAgL8="}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1.875,1.875,5],"min":[-1.875,-1.875,-5],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[0.6875,0.875],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":4,"componentType":5126,"count":4,"max":[1],"min":[0],"type":"SCALAR"},{"bufferView":5,"componentType":5126,"count":4,"max":[0,0,0,1],"min":[0,0,-0.8660253882408142,-1],"type":"VEC4"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{"sampler":0,"source":0,"name":"rgt_shaft"}],"samplers":[{"magFilter":9728,"minFilter":9728,"wrapS":33071,"wrapT":33071}],"images":[{"mimeType":"image/png","name":"rgt_shaft.png","uri":"rgt_shaft.png"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]}],"animations":[{"name":"animation","samplers":[{"input":4,"output":5,"interpolation":"LINEAR"}],"channels":[{"sampler":0,"target":{"node":1,"path":"rotation"}}]}]} \ No newline at end of file diff --git a/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/textures/rgt_hand_crank.png b/mods/rgt_machines/rgt_machines_mechanical/rgt_machines_mechanical/textures/rgt_hand_crank.png new file mode 100644 index 0000000000000000000000000000000000000000..6be57c06b80dc7c53d3913c03dea6df458bd6c0c GIT binary patch literal 820 zcmV-41Izr0P)Px%?ny*JR9J=WmOXCUKoEsL6Beo6!XiLGkPeW-K<*Ia20np-AdQ<8ZqnrfXC!B#2tq_=wv;N?{g9;yrfQs3^1yv2%oP70(3x;cKV40!30 z3nVVhQmS%GQQWuKdv*%s68|EfQZc{Kx-~OoT5B#YF7|c+y&3>`D1o9yb>nN-futjj zPbiIbz|$;ckt8ga%Yz^R+%10Iy;}nSajbeZ zAitZMnjU~|8+NJo8EFdb-u>^lp#UE0lDzwyNB^iRh1FHTsLb9ew@u_GxMx zO3Yo6W2+77)jJn|cl)iU5mmY6!{?j*S|GjbPrt!}>vV_z(&ciAjRIE7m8*qFtKGT# zt(StKS1>Xu<<&oK`x9~=YO1n03_!X-#HUfg4FD>fp~8PtP+l|?UzJ;zHt|g<$e=2> zEaHTpzkZWuDUnw0rIA)F;-pm{WAR}WP#W87<4FuKLif;N`{H4P-OUHzzZZbeD4if5 zB4HG?I>A@Fq4;`z#!NLawYAi6@M{Qv5H%WKw2(Wc1H#JFi-CAwg0YDf#y%eWJy{>^)K9u$wOl#%1IY87)6-M3EaUwA z{2=`Rfwh)A&oRbej5&zj?+B?8p<5~CRPg%x`e_P)L6lclS5HZjkmpT-$$BgWi`VZl y#!UJE>Dr(e`LFWV<8%Gyx%a-Px%G)Y83R9J=WR>4k#KoEVBx?4ENCM30gWBeem-uwZtp8OntMHADQm{3iCT@va6 zXB?&wp|rQY6W!f1Z{EC_<>Kl7W@l^!LhubVr_^WHZ91OTj88LChq&%XcwvAIO*GI6FJ6T2l4d;?#U9MmRpCn%u` z#ojt8uwG?&eR~Hbv;Fqt2^bso2Be?>I*JgMCV{bE{JXCtqX@`gOOvq7l9VhD{ibL9 z%1&jZ|BogRe8aU2KL6YK_MHp~ZI*c_W1vPEY6P#>Cnx|VBSej*r25QQw+|8^<3LDF z(2|oEoQnZ~m77HXzb3Ou+^N4Nq@Q2k-e(5~d0@TDctN(L3`pdt-&fb}I0_gWvAn6v zIu4gvr>-47TBX?pWEYel8|C1Gj;ZBaJs3>;ENJVlW?ZGErV|me1p`rvw!okneByzuA>~W5chzb{Z%Nq z3@zathhl-AOzGvCj3gyz|CGz8mjL#z+u{Ch6|1oocg37;U;@&F1X6~)fg{X*jnUdw zp*Tw4?-8I$2+?lT<4`J`0;~YZuLF@cPK5}n#yU8ypNd4s13Fu&Mmq-%Z?}I5P_|l$ zso!{$2?XD8*4zBEGv(;+?<>#I2n@+e-9hArrs7=i_W-qCDen2d_4yO;j5CJt18LTR UiyDOSU;qFB07*qoM6N<$g1Z1FzW@LL literal 0 HcmV?d00001 diff --git a/mods/rgt_materials/textures/rgt_iron_plating.png b/mods/rgt_materials/textures/rgt_iron_plating.png new file mode 100644 index 0000000000000000000000000000000000000000..9a691eac1d1ac44fffb4b7d774ea45be60ec9e11 GIT binary patch literal 278 zcmV+x0qOpUP)Px#&`Cr=R5*=|k+GJAFbG6hk4>OVX#HjXF|AS(+gFT>tgh!gs?ppKnE6@Pm0qfp z^87i!9iW&ww1^PVgpYmSg8&3E#sF$&?tWcptz|-0vvBuiSwK$F7zBj7t11y?AtEAj zUg*686%mXCB7~WpFO*W4xwVG&+qQwrU5O}0nz2(r@>_4d&Bt-{-oKCHH3w`m#$aX< zfv4BfIR{mJnszOnbI7~iOslp2u@%Pw#hoxWY&dN-GXxaSEr&2>!e+JBAaZK|=YZak cLmuE+AMG-T8qi16-T(jq07*qoM6N<$f+F&D1^@s6 literal 0 HcmV?d00001 diff --git a/mods/rgt_player/init.lua b/mods/rgt_player/init.lua index 0a033c0..6cc66ce 100644 --- a/mods/rgt_player/init.lua +++ b/mods/rgt_player/init.lua @@ -6,7 +6,8 @@ Player = { new = function(p) local m = setmetatable({ name = p:get_player_name(), - object = p + object = p, + listeners = {} }, {__index = Player}) m:set_hotbar_size(8) @@ -57,7 +58,7 @@ Player = { m.inv = Inventory(p) - m:dispatch("init") + Player:dispatch("init") return m end, @@ -110,8 +111,8 @@ Player = { shaded = false } end, - set_wielditem = function(m, def) - if not def then def = {name = ""} end + set_wielditem = function(m, s) + local def = s:get_definition() if not (m.wielditem_display and m.wielditem_display:is_valid()) then local mp = m.object:get_pos() or vector.zero() m.wielditem_display = minetest.add_entity(mp, "display") @@ -144,7 +145,7 @@ Player = { m.wielditem_display:set_properties { visual = "item", visual_size = scale, - wield_item = def.name + wield_item = s:to_string() } m.wielditem_display:set_attach(m.object, "RightArm", pos, rot) -- Apparently this forces a resend so that properties and attachment position will sync up? @@ -405,7 +406,7 @@ Player = { if onunselect then onunselect(m) end end m.prev_wielditem = wname - m:set_wielditem(def) + m:set_wielditem(w) local onselect = def and def.on_wield if onselect then onselect(m, w) end end @@ -413,7 +414,7 @@ Player = { local while_wielded = def and def.while_wielded if while_wielded then while_wielded(m, w) end - m:dispatch("tick") + m:dispatch("tick", m) end, set_hotbar_size = function(m, slots) local p = m.object diff --git a/mods/rgt_player/textures/object_crosshair.png b/mods/rgt_player/textures/object_crosshair.png index 5dc0468abb0f581949b49800df7cdd3841a03c50..ad79fa8a33c33a52d0d895f6ae58c82ada450a1d 100644 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|d_7$pLp(Z@ z6C_xbh5xiOWvxh8S~5}M@W+$JLW?I(oG7^3D(T9DEe#VGk4T(z(CGM(sp5K8L*fZT txSEogG2i7Lw;VMkx3?K?(yUXM86>{=zYT2sqX;yZ!PC{xWt~$(69D6&E};Mb literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|^gUf1Lo9le z6Am!{b7r(N_4%RF$+(y;fYIPlmzo<8q}b_|GQVftlVGBH=_CV#J+}mlUDK5&pjHM? LS3j3^P64%P)Px$S4l)cR9J=Wl`&4lFc3vwVy~2F8w$7q1qavz>Z-x-$p7{Xm%Y}5j*^8*|W)3-r-=lpO!B>0p7qE4s; z^xZkh-tzN|IAz!<-BH&hYtlQVUSqFbC%cwq2_hptd22F8pN>)i#ti$HQ4tJta1btCqyF zBh&)4Hq5yIP(MTfHvVp5RR=$=ws&bg|4Kki#1*pe;)Unpw;(2R35dEA^ZzDbtpmA4 zB?Aax!|f&2g~8(Fxw~QkVM`@oZlx~m`w|CKR8&+{Q~>+{6et~|`qAWK00000NkvXX Hu0mjf*Wt1k literal 0 HcmV?d00001 diff --git a/mods/rgt_things/rgt_lights/textures/rgt_lantern_iron.png b/mods/rgt_things/rgt_lights/textures/rgt_lantern_iron.png new file mode 100644 index 0000000000000000000000000000000000000000..970d95dcecca0cb0cb593551d358b542e794ff1f GIT binary patch literal 403 zcmV;E0c`$>P)Px$O-V#SR9J=WmN9O_FbqYXV|6gJ`Wjt&uoPKq&jq^nU_C-lkd+XU0(FOghCoP8 zsdn^VEPTP_*EdPIo2F?QhJhF(03t$434j)Up63n+f(AQ2&hYTf`^W3Lxy6^(D#U}s zn&jHU*MZ~H3o%BvcnjsmadZm^A_CW*<R4Jo+rmqK*6q1tSVv*q-(w4pt}}$z}iUNn)lvcu^l^h?AWnG@dNsi9*o3$cmn_c002ovPDHLkV1i<^vZw$6 literal 0 HcmV?d00001 diff --git a/mods/rgt_towns/rgt_towns_core/visuals.lua b/mods/rgt_towns/rgt_towns_core/visuals.lua index e256098..839ff9a 100644 --- a/mods/rgt_towns/rgt_towns_core/visuals.lua +++ b/mods/rgt_towns/rgt_towns_core/visuals.lua @@ -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 or "[fill:1x1:0,0:#faa", + texture = args and args.color and "[fill:1x1:0,0:"..args.color or args.texture or "[fill:1x1:0,0:#faa", time = 10, amount = 50, size = 5 diff --git a/mods/rgt_vehicles/rgt_vehicles/init.lua b/mods/rgt_vehicles/rgt_vehicles/init.lua new file mode 100644 index 0000000..e69de29 diff --git a/mods/rgt_vehicles/rgt_vehicles/mod.conf b/mods/rgt_vehicles/rgt_vehicles/mod.conf new file mode 100644 index 0000000..ca6aad8 --- /dev/null +++ b/mods/rgt_vehicles/rgt_vehicles/mod.conf @@ -0,0 +1,2 @@ +name = rgt_vehicles +depends = rgt_base, rgt_player \ No newline at end of file diff --git a/mods/rgt_world/init.lua b/mods/rgt_world/init.lua index a32456b..3ff4e12 100644 --- a/mods/rgt_world/init.lua +++ b/mods/rgt_world/init.lua @@ -76,6 +76,7 @@ for i = 1, 3 do tiles = {"rgt_grass_"..i..".png"}, groups = {attached_node = 3, dig_immediate = 3}, walkable = false, + buildable_to = true, selection_box = { type = "fixed", fixed = { @@ -96,6 +97,7 @@ rgt.register_node("grass_tall_bottom", { tiles = {"rgt_grass_tall.png^[verticalframe:2:1"}, groups = {attached_node = 3, dig_immediate = 3}, walkable = false, + buildable_to = true, selection_box = { type = "fixed", fixed = { @@ -147,6 +149,7 @@ rgt.register_node("grass_tall_top", { } }, drop = "grass_tall_bottom", + buildable_to = true, after_destruct = function(pos) local below = pos:offset(0, -1, 0) local nb = minetest.get_node(below) @@ -191,57 +194,7 @@ rgt.register_node("sand", { groups = {dig_immediate = 3} }) - -rgt.register_node("oak_log", { - tiles = {"rgt_oak_log_top.png", "rgt_oak_log_top.png", "rgt_oak_log_side.png"}, - groups = {dig_immediate = 3}, - paramtype2 = "facedir" -}) - -rgt.register_node("oak_leaves", { - drawtype = "allfaces", - tiles = {"rgt_oak_leaves.png"}, - use_texture_alpha = "clip", - groups = {dig_immediate = 3}, -}) - -rgt.register_node("oak_planks", { - tiles = {{name = "rgt_oak_planks.png", align_style = "world"}}, - _variants = "all", - groups = {dig_immediate = 3}, -}) - -rgt.register_node("dark_planks", { - tiles = {{name = "rgt_dark_planks.png", align_style = "world"}}, - _variants = "all", - groups = {dig_immediate = 3}, -}) - -rgt.register_node("spruce_planks", { - tiles = {{name = "rgt_spruce_planks.png", align_style = "world"}}, - _variants = "all", - groups = {dig_immediate = 3}, -}) - -rgt.register_node("acacia_planks", { - tiles = {{name = "rgt_acacia_planks.png", align_style = "world"}}, - _variants = "all", - groups = {dig_immediate = 3}, -}) - -rgt.register_node("redwood_planks", { - tiles = {{name = "rgt_redwood_planks.png", align_style = "world"}}, - _variants = "all", - groups = {dig_immediate = 3}, -}) - -rgt.register_node("birch_planks", { - tiles = {{name = "rgt_birch_planks.png", align_style = "world"}}, - _variants = "all", - groups = {dig_immediate = 3}, -}) - - +include "wood.lua" rgt.register_node("glass", { drawtype = "glasslike", @@ -266,6 +219,19 @@ rgt.register_node("basalt", { groups = {dig_immediate = 3}, }) +rgt.register_node("basalt_tile", { + tiles = {{name = "rgt_basalt_tile.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + + +rgt.register_node("basalt_brick_large", { + tiles = {{name = "rgt_basalt_brick_large.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + rgt.register_node("water", { tiles = {"[fill:16x16:0,0:#2d5a7c77^[fill:14x14:1,1:#2d5a7c33"}, @@ -443,26 +409,26 @@ minetest.register_decoration { fill_ratio = 0.2, } -minetest.override_item("", { - on_place = function(s, p, pt) - if minetest.get_node(pt.under).name:find "dirt_grass" then - minetest.set_node(pt.under, {name = "path_grass"}) - end --- minetest.spawn_tree(pt.above, { --- axiom = "TF[FFA]", --- rules_a = "F", --- trunk = "oak_log", --- leaves = "oak_leaves", --- angle = 30, --- iterations = 2, --- random_level = 0, --- trunk_type = "single", ----- thin_branches = true, --- fruit_chance = 0, --- fruit = "stone_brick" --- }) - end -}) +--minetest.override_item("", { +-- on_place = function(s, p, pt) +-- if minetest.get_node(pt.under).name:find "dirt_grass" then +-- minetest.set_node(pt.under, {name = "path_grass"}) +-- end +---- minetest.spawn_tree(pt.above, { +---- axiom = "TF[FFA]", +---- rules_a = "F", +---- trunk = "oak_log", +---- leaves = "oak_leaves", +---- angle = 30, +---- iterations = 2, +---- random_level = 0, +---- trunk_type = "single", +------ thin_branches = true, +---- fruit_chance = 0, +---- fruit = "stone_brick" +---- }) +-- end +--}) minetest.register_chatcommand("biome", { func = function(name) diff --git a/mods/rgt_world/textures/rgt_acacia_planks.png b/mods/rgt_world/textures/rgt_acacia_planks.png index f6b6c65764b0ac20146a00de6fa436a1c8a24212..472e6f12c641cb2eff23795f23e8931638657579 100644 GIT binary patch delta 280 zcmV+z0q6dZ0>A>0F@O3=L_t(IjdhYuYQr!Pg};I{0&5ZIPoR*q^jf`N&k_j8ali%} zY-`cQsFIM=x3Xu(Pv7(C<>&ir+h<^3RsgV_qmoz;^h5Y~I|C+{RDB|@N&hP%eKU*tZ4JYi&sth?mLz}L~k=}N$Sy{c7yobWd6zjE= eo3=!le*rWVo)PHmlGH8$0000jhHl;}AduupkKyC~{05bCQaP2JW&jW+6vUtLi&Axv8GG@!kk-M(-@d@w hpzomZn+Efzy#a0Lb9Fmnsf+*s002ovPDHLkV1gaYbAtc? diff --git a/mods/rgt_world/textures/rgt_basalt.png b/mods/rgt_world/textures/rgt_basalt.png index ecb1e68e519ba2e0c191616b4ec2204b48246405..a1b5596d32ce347c776b215ac77b471157d2cff7 100644 GIT binary patch delta 173 zcmV;e08;|G&^c_CQ0ah+7T@0?Z8HHO8Q~ zsVWr)fIVofEzV*hLPTtM04)AX#l80m3_#{*2d<=Bo0svDs0MImUVv3KD#_#wV2c`e z5FyxehxNx!{Az#q=O#;XC;S|pu{A<{Im?q?wiCTO(BC@+Ymi;*7 zZK^5*13-7y70sowQdC4}cmT}*q~f+QzgjX-shpM$Jd$o{{*6swRDd(H0an$hB$E?B z7d7@ELeOKA_Qy>AY=31q&uawMt)w%DJVE0(35?;%DC!)1H7V?zRPso2t>$ME|6rG= eOQmRcbF$qn6j!zPazeQP0000Px#-AP12R5*=&Qp*y;FbLcLJ=XCz9B2Ih&+=8L8UYW~n8xTHGI_wlZb*my4r{nO ze&9CW1;8{v05J2fxPYnx5O+5-B8qbjGi#IFgqeq7=#mjpxrzF2DrOeX9X_C>E%n`` zdHAnHpSEbI`>s1_#kk4odZm&UYwwv)gA*Cd9Zruze%zV4& zkK8vT=iCveTHI@tNcR)cT2-kDKx&%ehP&79)pHPx#yGcYrR5*=&QdL{L{m(UZ(zXoP2UVI!TYrLsZ8`k7->64K&YJ`m9O>kH(>f5tZJ4qv-q+&cR#QC`14Ck{>V}ER$9#zRHWd>Vz3_q%p zoZCqn*_6zOaV8nkl>z`LEAwSgpGrRuad$gWh)8V)Y1eTa#u*F$Sn}`Lnhh#Tq;?%f z8yE$kHuomd?Fk^z=OwqlKNji(5w?S$FfEuN$H$>Z~b(kmE0H9Hd*m0OAwqQkWH2w|1Y|muJ zsbB+1Eu_x7uSYnZ#EuLdj^{PN!um~&N>Wb3hQ2x8>>9`VA^G*U0QnY=#M$db8NT9A5i?_ks0YFrui1;)9sFWR~9d_a`A-MyK mzns9*kmiu$XAR{v0DJ(7$Zq$IQi2Nr0000#wN#h3TV49Swkrx152S(033dfx+pUtXUx zz|bz*<|p3?vanPlLIB+7lEpQCP)c0#O!V5jq;pg(6+`S5 zPAjE6P2r0S&f~ZS$jW*o2Fr>N5qK-zCYCHni7jViB~mx<16M2HYKZ+-X>qXkuA!?_ z!tTC}0PC^E@VLKBuCuwNlgjcWB2|JS{#?H*eH?Vg(fTcsFR%pKJGAw0ewgj? Y4eL^JA>M=Ke*gdg07*qoM6N<$f|>1Vz5oCK diff --git a/mods/rgt_world/textures/rgt_oak_planks.png b/mods/rgt_world/textures/rgt_oak_planks.png index d5e0b4ad33c635d97fba56d92ef793f648c259da..dfb5a7d6c52e25866ec67a3036e6d3e674ebf3ff 100644 GIT binary patch delta 273 zcmV+s0q*{g0=WW^F@N((L_t(IjdhaIio!4uMXzN@YF<`YP!aUM{4T#_e@Q`NKu8rD zn}YZ-bvmZ*eF(`Uxjna&+23LR$Sr`bO#lE`H-}Pf8~`8udbtKbQsQx{M{e1ReMx3o z^0lAEFB_%Y^MrixxqE)~HnvK^%hCrAfS62lJe_yj%~vqSrhg`0Ii=1Z+XZkFuT-2i zwvv=wuZ`0citz>jxQWfXg67@1HvT}Go|8QZs<$XyqO1j! zm2xj50B#pC;_-A|t``6OS*_t|7+V!2(^SLLn9^G}FIuMCB7GQHQ|@(J#+P>QfcOHV Xs-$k|5P0hV015yANkvXXu0mjf>RW!s delta 231 zcmV{28r97Ya@ivu0i_j3tSh{eL zl8n<>omDbF$@|_M?zb!ch`@`p1b~jNE_PUx^E^+1J%FRDNtJn?)IkOHgP&gj{I+H) zttzl5X9+fEpX1V;Xa|PQ&E-SDxN7|dMpCOawW<6TI=#sAL}2|O)%&Csh-{jNqPyj= z1*DZh{wu?H;>YNNKz48r)F47`L#2OuI*l=##Bh?E%ucRTh=k(xo-FE_9b hq&+12)qvavfH#{Na9j1QiNpW^002ovPDHLkV1gKnajXCU diff --git a/mods/rgt_world/textures/rgt_polished_basalt_tile.png b/mods/rgt_world/textures/rgt_polished_basalt_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..9532fd856af324b848969c9fe35cddc8bd947490 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|8a-VcLo9ly z21WB7P~dQWAlLnU|DwX*1_wXQIQ@$~=oZ`UtJZ%Tg#?Y~w@ZDtRTtdI5xtsGcS?4Z zc1xI^pnRIo1;I`89Xh7n`y;XWM8G1SM^~D+3;8XK*%@|2_(=FsMV^Lkv&6o}pll86 wlIYDFbAsNkmRZ+r*kzq^#CpStnGF>TySKZ}Vp6@h7U&oTPgg&ebxsLQ0J29)ssI20 literal 0 HcmV?d00001 diff --git a/mods/rgt_world/textures/rgt_redwood_planks.png b/mods/rgt_world/textures/rgt_redwood_planks.png index d197eda33fe138b62447a3841d1dc71ffae8a64c..b282c0d198a12b4c6d56f42f91cd8e9dc6ca446a 100644 GIT binary patch delta 266 zcmV+l0rmcn0-F@NkyL_t(IjdhYiZo?oDMSrDX6vfJ-j-smP>4AE$Tr9GX$-)Y$ zfJGKVh6$v9Vc{A0e&55#`S&N~8-Vhc005vJ!-(AkU=98_p8$}SB>sK zwm*DUqg-S`Yw#(*wFW!fgV)zJcmO11s>|ZPzfR*}p#LME3^Zvg-YgMlXyPjlBRj2yTutc^e{{An z+tB=Ko1}T)%kFwP{crr`EpKEgd_kBJ2L4sMRPDgV;`RJ1w59y*6)of zNFrv(Twl8(o{oOmTqp41@Fie~S?d-UX|0ZY>%$Vd{FtUlV_+ZDdnj6g%w~CrH>Lw% zUO}1}^jsb7$Nt)|>bC+2`C7{8eybZ$##b!MNR%c1v_B(NhNadmk(R;OuQxC^ hlsy#tO@rPBfHz*rZ;m5vIqd)d002ovPDHLkV1jXSX#D^H diff --git a/mods/rgt_world/textures/rgt_spruce_leaves.png b/mods/rgt_world/textures/rgt_spruce_leaves.png new file mode 100644 index 0000000000000000000000000000000000000000..4e99c0189d165f0d79e87fb36ae7996d13b73702 GIT binary patch literal 372 zcmV-)0gL{LP)Px$E=fc|R5*=ok}-~jFbqUrqAemS%C9e~EjU6-4o{gQP;7+|B^BB(TQCm(XwyJq zduD780AwouWGbV3n;!9z%5c5KkHnEmrg8v1SQ0a#k&IM&;C;ozM}eIKIQ8GT*rvh_ zSTE2>A+(|d6auFbtoTsTw}9R^Q3PNiG?q+d6{x)}1XcpOBhd-1Cu?JK3`M;s&B5l? z-ypFSFGB4EVk`;Rof1KP)Px$FG)l}R5*=QQoC-$Fbt$fQ85^}jt2vQr~dz6b@Ac?DPS~B^hyUBjLboRMBedu zl>592lbgqG-68;_TmgVRrd-*h1iHsE_2Ktf?y;m?5t`8IdF<@ve4>=Aa%t><<@Nx8 zLD&+5aLSd*9T>|CncN^ekDZAzZUFfD{)1y2It1?kzyu7!>`~h)eg~XS#2$@X0!@8b zZVxL;xhmrhShpyF0Dx)7Yubv`2?@mHFqKzpQ9E>dUAK6T{?=jwat;qNg!o4f2KZIg&C+YWRL2G1WLK;YK?g6!}Re6zh^L~m2cgmUe_%$ zA$!yl08ppYnRHX_UsAP)4rZ&d>i=n%VC!dc*qX3zG3C1aJk2Gw`y&1#ULXGfWksKD T*RU5W00000NkvXXu0mjfu6Lx5 literal 0 HcmV?d00001 diff --git a/mods/rgt_world/textures/rgt_spruce_log_top.png b/mods/rgt_world/textures/rgt_spruce_log_top.png new file mode 100644 index 0000000000000000000000000000000000000000..295b3dbe1b4307c362ab0e642e58c5a79a2c0a33 GIT binary patch literal 420 zcmV;V0bBlwP)Px$UP(kjR5*>5QoBwAF%XNPEJNFL`paUgPCyCH*4C5JS+-3VfWIkzkT literal 0 HcmV?d00001 diff --git a/mods/rgt_world/textures/rgt_spruce_planks.png b/mods/rgt_world/textures/rgt_spruce_planks.png index 7efa3b81a002708c9f7dcc97cc878c76c16012c2..bae7d87bacea7924daef98bd4a5158410b289e8f 100644 GIT binary patch delta 266 zcmV+l0rmcl0-F@NkyL_t(IjdhY;j>8}fgr~uvYPaf-dXYU$kI}0~4XA`DkZK=H z9WUw5Lj;CQzKOlN-+pqL0W9+j0Dy50N|qdeA^7w01c0Q(&#iKq*^7NiR$B74{nw!y zmBb4gf?x9Mqqni$6ufMQ-~kYmiTeI=yBLJi4K!JGEct Q00000NkvXXt^-0~f~&HEB>(^b delta 229 zcmV$8$lrAz=!i45^){HC-xq%wVpzlDqrA^vs)^MLQc f;|~MvHUK;UnD}y1YY5|t00000NkvXXu0mjf{|jf} diff --git a/mods/rgt_world/variants.lua b/mods/rgt_world/variants.lua index e4e0412..31307f5 100644 --- a/mods/rgt_world/variants.lua +++ b/mods/rgt_world/variants.lua @@ -5,6 +5,7 @@ function ns.register_slab(def) def._variants = nil rgt.register_node(def._name.."_slab", extend(def, { + _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", @@ -49,6 +50,92 @@ function ns.update_stair(pos, basename, leaf) end end +local function get_connection_dirs(dir, variant, orientation) + if variant == "stair_inner" then + if orientation == "back" then + return dir:rotate(vector.new(0, math.pi, 0)), dir:rotate(vector.new(0, -math.pi /2, 0)) + else + return dir:rotate(vector.new(0, math.pi /2, 0)), dir + end + elseif variant == "stair_outer" then + if orientation == "back" then + return dir:rotate(vector.new(0, math.pi /2, 0)), dir + else + return dir:rotate(vector.new(0, math.pi, 0)), dir:rotate(vector.new(0, -math.pi /2, 0)) + end + elseif variant == "stair" then + return dir:rotate(vector.new(0, math.pi /2, 0)), dir:rotate(vector.new(0, -math.pi /2, 0)) + end + + return vector.zero(), vector.zero() +end + +local function place_stair(s, p, pt) + local m = rgt.players[p:get_player_name()] + local def = s:get_definition() + local out = ItemStack(s) + local variant = def._variant + local param2 + + s:set_name(def._base_node.."_stair") + + local invert = m.pointed_node.intersection_point.y -m.pointed_node.under.y > 0.5 + local adjusted_yaw = (math.pi *2 -m.yaw) +(math.pi /4) + if adjusted_yaw > math.pi *2 then + adjusted_yaw = adjusted_yaw -(math.pi *2) + end + local yaw = math.floor(adjusted_yaw /(math.pi /2)) + local dir = vector.new(yaw == 1 and 1 or yaw == 3 and -1 or 0, 0, yaw == 0 and 1 or yaw == 2 and -1 or 0) + local dir_left = dir:rotate(vector.new(0, -math.pi /2, 0)) + local dir_right = dir_left:rotate(vector.new(0, math.pi /2, 0)) + +-- local obj = minetest.add_entity(pt.above +dir, "display") +-- obj:set_properties { +-- visual = "cube", +-- textures = {"rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99", "rgt_glass.png^[multiply:#f99"} +-- } + +-- minetest.after(10, function() obj:remove() end) + + local front = minetest.get_node(pt.above +dir) + local front_def = minetest.registered_nodes[front.name] + local back = minetest.get_node(pt.above -dir) + local back_def = minetest.registered_nodes[back.name] + local left = minetest.get_node(pt.above +dir_left) + local left_def = minetest.registered_nodes[left.name] + local right = minetest.get_node(pt.above +dir_right) + + if (front_def._variant or "none"):find "stair" then + local front_dir = minetest.facedir_to_dir(front.param2) + local dir_a, dir_b = get_connection_dirs(front_dir, front_def._variant) + + if dir_a == dir then + s:set_name(def._base_node.."_stair_outer") + param2 = minetest.dir_to_facedir(dir_left) + elseif dir_b == dir then + s:set_name(def._base_node.."_stair_outer") + param2 = minetest.dir_to_facedir(dir_right) + end + elseif (back_def._variant or "none"):find "stair" then + local back_dir = minetest.facedir_to_dir(back.param2) + local dir_a, dir_b = get_connection_dirs(back_dir, back_def._variant, "back") + + if dir_a == dir then + s:set_name(def._base_node.."_stair_inner") + param2 = minetest.dir_to_facedir(dir_left) + elseif dir_b == dir then + s:set_name(def._base_node.."_stair_inner") + param2 = minetest.dir_to_facedir(dir_right) + end + end + + local stack = minetest.item_place_node(s, p, pt, param2) + + out:set_count(stack:get_count()) + + return out +end + function ns.register_stair(def) def = table.copy(def) def._variants = nil @@ -56,36 +143,75 @@ function ns.register_stair(def) def.groups[def._name.."_stair"] = 1 rgt.register_node(def._name.."_stair", extend(table.copy(def), { + _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", - fixed = {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, -0.5, 0, 0.5, 0.5, 0.5}} + fixed = { + { + -0.5, -0.5, -0.5, + 0.5, 0, 0.5 + }, + { + -0.5, -0.5, 0, + 0.5, 0.5, 0.5 + }, + } }, paramtype = "light", paramtype2 = "facedir", _variant = "stair", + on_place = place_stair, })) rgt.register_node(def._name.."_stair_inner", extend(table.copy(def), { + _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", - fixed = {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, -0.5, 0, 0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5, 0, 0.5, 0.5}} + fixed = { + { + -0.5, -0.5, -0.5, + 0.5, 0, 0.5 + }, + { + -0.5, -0.5, -0.5, + 0, 0.5, 0.5 + }, + { + -0.5, -0.5, 0, + 0.5, 0.5, 0.5 + }, + } }, paramtype = "light", paramtype2 = "facedir", _variant = "stair_inner", + on_place = place_stair, + drop = def._name.."_stair", })) rgt.register_node(def._name.."_stair_outer", extend(def, { + _base_node = def._name, drawtype = "nodebox", node_box = { type = "fixed", - fixed = {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, -0.5, 0.5, 0, 0.5, 0}} + fixed = { + { + -0.5, -0.5, -0.5, + 0.5, 0, 0.5 + }, + { + -0.5, -0.5, 0.5, + 0, 0.5, 0 + } + } }, paramtype = "light", paramtype2 = "facedir", _variant = "stair_outer", + on_place = place_stair, + drop = def._name.."_stair", })) end diff --git a/mods/rgt_world/wood.lua b/mods/rgt_world/wood.lua new file mode 100644 index 0000000..acd7f34 --- /dev/null +++ b/mods/rgt_world/wood.lua @@ -0,0 +1,350 @@ + +-- MARK: Helpers + +local fence_nodebox = { + type = "connected", + fixed = { + -2/16, -0.5, -2/16, + 2/16, 0.5, 2/16 + }, + connect_front = { + { + -1/16, -6/16, -0.5, + 1/16, -2/16, 0 + }, + { + -1/16, 2/16, -0.5, + 1/16, 6/16, 0 + } + }, + connect_back = { + { + -1/16, -6/16, 0, + 1/16, -2/16, 0.5 + }, + { + -1/16, 2/16, 0, + 1/16, 6/16, 0.5 + } + }, + connect_left = { + { + -0.5, -6/16, -1/16, + 0, -2/16, 1/16 + }, + { + -0.5, 2/16, -1/16, + 0, 6/16, 1/16 + } + }, + connect_right = { + { + 0, -6/16, -1/16, + 0.5, -2/16, 1/16 + }, + { + 0, 2/16, -1/16, + 0.5, 6/16, 1/16 + } + }, +} + +local fence_gate_nodebox = { + type = "fixed", + fixed = { + { + -8/16, -7/16, -1/16, + -6/16, 7/16, 1/16 + }, + { + 8/16, -7/16, -1/16, + 6/16, 7/16, 1/16 + }, + { + -6/16, -6/16, -1/16, + 6/16, -2/16, 1/16 + }, + { + -6/16, 2/16, -1/16, + 6/16, 6/16, 1/16 + } + } +} + +local fence_gate_open_nodebox = { + type = "fixed", + fixed = { + { + -8/16, -7/16, -1/16, + -6/16, 7/16, 1/16 + }, + { + 8/16, -7/16, -1/16, + 6/16, 7/16, 1/16 + }, + + { + -8/16, -6/16, 1/16, + -6/16, -2/16, 0.5 + }, + { + -8/16, 2/16, 1/16, + -6/16, 6/16, 0.5 + }, + + { + 8/16, -6/16, 1/16, + 6/16, -2/16, 0.5 + }, + { + 8/16, 2/16, 1/16, + 6/16, 6/16, 0.5 + }, + } +} + +local ladder_nodebox = { + type = "fixed", + fixed = { + { + -7/16, -0.5, 0.5, + -5/16, 0.5, 6/16 + }, + { + 5/16, -0.5, 0.5, + 7/16, 0.5, 6/16 + }, + { + -5/16, -7/16, 7.5/16, + 5/16, -5/16, 6.5/16 + }, + { + -5/16, -3/16, 7.5/16, + 5/16, -1/16, 6.5/16 + }, + { + -5/16, 1/16, 7.5/16, + 5/16, 3/16, 6.5/16 + }, + { + -5/16, 5/16, 7.5/16, + 5/16, 7/16, 6.5/16 + }, + } +} + +local log_nodebox = { + type = "fixed", + fixed = { + { + -6/16, -0.5, -0.5, + 6/16, 0.5, 0.5, + }, + { + -0.5, -0.5, -6/16, + 0.5, 0.5, 6/16, + } + } +} + +function rgt.register_fence(name, texture) + rgt.register_node(name.."_fence", { + drawtype = "nodebox", + node_box = fence_nodebox, + connects_to = {"group:fence"}, + paramtype = "light", + sunlight_propagates = true, + tiles = {{name = texture or "rgt_"..name.."_planks.png", align_style = "world"}}, + groups = {dig_immediate = 3, fence = 1}, + }) + + local function fence_gate_swap(pos, node, p) + if node.name:find "fence_gate_open" then + node.name = node.name:gsub("fence_gate_open", "fence_gate") + elseif node.name:find "fence_gate" then + node.name = node.name:gsub("fence_gate", "fence_gate_open") + + local rot = minetest.fourdir_to_dir(node.param2) + -- Get the axis on which the gate will open. + local axis = rot.x ~= 0 and "x" or "z" + local dir = p:get_pos():direction(pos) + -- If the gate will open in the opposite direction from the player's facing direction, flip it. + if math.sign(dir[axis]) ~= math.sign(rot[axis]) then + node.param2 = (node.param2 +2) %4 + end + end + minetest.swap_node(pos, node) + end + + rgt.register_node(name.."_fence_gate", { + drawtype = "nodebox", + node_box = fence_gate_nodebox, + connects_to = {"group:fence"}, + connect_sides = {"left", "right"}, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "4dir", + tiles = {{name = "rgt_"..name.."_planks.png", align_style = "world"}}, + groups = {dig_immediate = 3, fence = 1}, + on_rightclick = fence_gate_swap, + }) + + rgt.register_node(name.."_fence_gate_open", { + drawtype = "nodebox", + node_box = fence_gate_open_nodebox, + connects_to = {"group:fence"}, + connect_sides = {"left", "right"}, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "4dir", + tiles = {{name = "rgt_"..name.."_planks.png", align_style = "world"}}, + groups = {dig_immediate = 3, fence = 1}, + on_rightclick = fence_gate_swap, + }) +end + +function rgt.register_ladder(name) + rgt.register_node(name.."_ladder", { + drawtype = "nodebox", + node_box = ladder_nodebox, + selection_box = { + type = "fixed", + fixed = {-7/16, -0.5, 0.5, 7/16, 0.5, 6/16} + }, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "4dir", + climbable = true, + tiles = {{name = "rgt_"..name.."_planks.png", align_style = "world"}}, + groups = {dig_immediate = 3, ladder = 1}, + on_place = function(s, p, pt) + local under = minetest.get_node(pt.under) + -- If placing a ladder against a ladder, attempt to extend the pointed ladder rather than naively placing against it. + if under.name:find "ladder" then + local old_pt = table.copy(pt) + -- This will blow up for touchscreen users, but there's no way around it because they don't obey crosshair restrictions. + local iy = rgt.players[p:get_player_name()].pointed_node + -- `iy` can be nil in edge cases where the client clicked the node momentarily but is no longer pointing at the + -- node on the server when the message arrives and the server responds. In these cases, we just don't place anything + -- because we cannot determine the direction in which the player wishes to extend the ladder. + if not iy then return end + iy = iy.intersection_point.y + + -- Try extending in the pointed direction first. + pt.above = pt.under:offset(0, iy -pt.under.y > 0 and 1 or -1, 0) + local s, success = minetest.item_place_node(s, p, pt, under.param2) + if success then return s end + + -- If we can't, try extending in the other direction. + pt.above = pt.under:offset(0, iy -pt.under.y > 0 and -1 or 1, 0) + s, success = minetest.item_place_node(s, p, pt, under.param2) + if success then return s end + + -- If that too fails, don't place anything. We could fall back to default placement, but that would make rapid laddering more annoying. + else + return minetest.item_place_node(s, p, pt) + end + end + }) +end + +-- MARK: Oak + +rgt.register_node("oak_log", { + drawtype = "nodebox", + node_box = log_nodebox, + tiles = {"rgt_oak_log_top.png", "rgt_oak_log_top.png", "rgt_oak_log_side.png"}, + groups = {dig_immediate = 3}, + paramtype2 = "facedir", +}) + +rgt.register_node("oak_leaves", { + drawtype = "allfaces", + tiles = {"rgt_oak_leaves.png"}, + use_texture_alpha = "clip", + groups = {dig_immediate = 3}, +}) + +rgt.register_node("oak_planks", { + tiles = {{name = "rgt_oak_planks.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + +rgt.register_fence("oak") +rgt.register_ladder("oak") + + +-- MARK: Dark + +rgt.register_node("dark_planks", { + tiles = {{name = "rgt_dark_planks.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + +rgt.register_fence("dark") +rgt.register_ladder("dark") + + +-- MARK: Spruce + +rgt.register_node("spruce_log", { + drawtype = "nodebox", + node_box = log_nodebox, + tiles = {"rgt_spruce_log_top.png", "rgt_spruce_log_top.png", "rgt_spruce_log_side.png"}, + groups = {dig_immediate = 3}, + paramtype2 = "facedir", +}) + +rgt.register_node("spruce_planks", { + tiles = {{name = "rgt_spruce_planks.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + +rgt.register_node("spruce_leaves", { + drawtype = "allfaces", + tiles = {"rgt_spruce_leaves.png"}, + use_texture_alpha = "clip", + groups = {dig_immediate = 3}, +}) + +rgt.register_fence("spruce") +rgt.register_ladder("spruce") + + +-- MARK: Acacia + +rgt.register_node("acacia_planks", { + tiles = {{name = "rgt_acacia_planks.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + +rgt.register_fence("acacia") +rgt.register_ladder("acacia") + + +-- MARK: Redwood + +rgt.register_node("redwood_planks", { + tiles = {{name = "rgt_redwood_planks.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + +rgt.register_fence("redwood") +rgt.register_ladder("redwood") + + +-- MARK: Birch + +rgt.register_node("birch_planks", { + tiles = {{name = "rgt_birch_planks.png", align_style = "world"}}, + _variants = "all", + groups = {dig_immediate = 3}, +}) + +rgt.register_fence("birch") +rgt.register_ladder("birch")